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