• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 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     /**
214      * Gets the display name of the specified {@link MeasureUnit} corresponding to the current
215      * locale and format width.
216      * @param unit  The unit for which to get a display name.
217      * @param status the error.
218      * @return  The display name in the locale and width specified in
219      *          {@link MeasureFormat#getInstance}, or null if there is no display name available
220      *          for the specified unit.
221      *
222      * @stable ICU 58
223      */
224     UnicodeString getUnitDisplayName(const MeasureUnit& unit, UErrorCode &status) const;
225 
226 
227     /**
228      * Return a formatter for CurrencyAmount objects in the given
229      * locale.
230      * @param locale desired locale
231      * @param ec input-output error code
232      * @return a formatter object, or NULL upon error
233      * @stable ICU 3.0
234      */
235     static MeasureFormat* U_EXPORT2 createCurrencyFormat(const Locale& locale,
236                                                UErrorCode& ec);
237 
238     /**
239      * Return a formatter for CurrencyAmount objects in the default
240      * locale.
241      * @param ec input-output error code
242      * @return a formatter object, or NULL upon error
243      * @stable ICU 3.0
244      */
245     static MeasureFormat* U_EXPORT2 createCurrencyFormat(UErrorCode& ec);
246 
247     /**
248      * Return the class ID for this class. This is useful only for comparing to
249      * a return value from getDynamicClassID(). For example:
250      * <pre>
251      * .   Base* polymorphic_pointer = createPolymorphicObject();
252      * .   if (polymorphic_pointer->getDynamicClassID() ==
253      * .       erived::getStaticClassID()) ...
254      * </pre>
255      * @return          The class ID for all objects of this class.
256      * @stable ICU 53
257      */
258     static UClassID U_EXPORT2 getStaticClassID(void);
259 
260     /**
261      * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. This
262      * method is to implement a simple version of RTTI, since not all C++
263      * compilers support genuine RTTI. Polymorphic operator==() and clone()
264      * methods call this method.
265      *
266      * @return          The class ID for this object. All objects of a
267      *                  given class have the same class ID.  Objects of
268      *                  other classes have different class IDs.
269      * @stable ICU 53
270      */
271     virtual UClassID getDynamicClassID(void) const;
272 
273  protected:
274     /**
275      * Default constructor.
276      * @stable ICU 3.0
277      */
278     MeasureFormat();
279 
280 #ifndef U_HIDE_INTERNAL_API
281 
282     /**
283      * ICU use only.
284      * Initialize or change MeasureFormat class from subclass.
285      * @internal.
286      */
287     void initMeasureFormat(
288             const Locale &locale,
289             UMeasureFormatWidth width,
290             NumberFormat *nfToAdopt,
291             UErrorCode &status);
292     /**
293      * ICU use only.
294      * Allows subclass to change locale. Note that this method also changes
295      * the NumberFormat object. Returns TRUE if locale changed; FALSE if no
296      * change was made.
297      * @internal.
298      */
299     UBool setMeasureFormatLocale(const Locale &locale, UErrorCode &status);
300 
301     /**
302      * ICU use only.
303      * Let subclass change NumberFormat.
304      * @internal.
305      */
306     void adoptNumberFormat(NumberFormat *nfToAdopt, UErrorCode &status);
307 
308     /**
309      * ICU use only.
310      * @internal.
311      */
312     const NumberFormat &getNumberFormat() const;
313 
314     /**
315      * ICU use only.
316      * @internal.
317      */
318     const PluralRules &getPluralRules() const;
319 
320     /**
321      * ICU use only.
322      * @internal.
323      */
324     Locale getLocale(UErrorCode &status) const;
325 
326     /**
327      * ICU use only.
328      * @internal.
329      */
330     const char *getLocaleID(UErrorCode &status) const;
331 
332 #endif /* U_HIDE_INTERNAL_API */
333 
334  private:
335     const MeasureFormatCacheData *cache;
336     const SharedNumberFormat *numberFormat;
337     const SharedPluralRules *pluralRules;
338     UMeasureFormatWidth width;
339 
340     // Declared outside of MeasureFormatSharedData because ListFormatter
341     // objects are relatively cheap to copy; therefore, they don't need to be
342     // shared across instances.
343     ListFormatter *listFormatter;
344 
345     const SimpleFormatter *getFormatterOrNull(
346             const MeasureUnit &unit, UMeasureFormatWidth width, int32_t index) const;
347 
348     const SimpleFormatter *getFormatter(
349             const MeasureUnit &unit, UMeasureFormatWidth width, int32_t index,
350             UErrorCode &errorCode) const;
351 
352     const SimpleFormatter *getPluralFormatter(
353             const MeasureUnit &unit, UMeasureFormatWidth width, int32_t index,
354             UErrorCode &errorCode) const;
355 
356     const SimpleFormatter *getPerFormatter(
357             UMeasureFormatWidth width,
358             UErrorCode &status) const;
359 
360     int32_t withPerUnitAndAppend(
361         const UnicodeString &formatted,
362         const MeasureUnit &perUnit,
363         UnicodeString &appendTo,
364         UErrorCode &status) const;
365 
366     UnicodeString &formatMeasure(
367         const Measure &measure,
368         const NumberFormat &nf,
369         UnicodeString &appendTo,
370         FieldPosition &pos,
371         UErrorCode &status) const;
372 
373     UnicodeString &formatMeasuresSlowTrack(
374         const Measure *measures,
375         int32_t measureCount,
376         UnicodeString& appendTo,
377         FieldPosition& pos,
378         UErrorCode& status) const;
379 
380     UnicodeString &formatNumeric(
381         const Formattable *hms,  // always length 3: [0] is hour; [1] is
382                                  // minute; [2] is second.
383         int32_t bitMap,   // 1=hour set, 2=minute set, 4=second set
384         UnicodeString &appendTo,
385         UErrorCode &status) const;
386 
387     UnicodeString &formatNumeric(
388         UDate date,
389         const DateFormat &dateFmt,
390         UDateFormatField smallestField,
391         const Formattable &smallestAmount,
392         UnicodeString &appendTo,
393         UErrorCode &status) const;
394 };
395 
396 U_NAMESPACE_END
397 
398 #endif // #if !UCONFIG_NO_FORMATTING
399 #endif // #ifndef MEASUREFORMAT_H
400