Home | History | Annotate | Download | only in unicode
      1 /*
      2  *******************************************************************************
      3  * Copyright (C) 2010, Google, International Business Machines Corporation and *
      4  * others. All Rights Reserved.                                                *
      5  *******************************************************************************
      6  */
      7 
      8 #ifndef __TMUTFMT_H__
      9 #define __TMUTFMT_H__
     10 
     11 #include "unicode/utypes.h"
     12 
     13 /**
     14  * \file
     15  * \brief C++ API: Format and parse duration in single time unit
     16  */
     17 
     18 
     19 #if !UCONFIG_NO_FORMATTING
     20 
     21 #include "unicode/unistr.h"
     22 #include "unicode/tmunit.h"
     23 #include "unicode/tmutamt.h"
     24 #include "unicode/measfmt.h"
     25 #include "unicode/numfmt.h"
     26 #include "unicode/plurrule.h"
     27 
     28 /**
     29  * @internal ICU 4.2
     30  */
     31 
     32 union UHashTok;
     33 
     34 U_NAMESPACE_BEGIN
     35 
     36 class Hashtable;
     37 
     38 
     39 /**
     40  * Format or parse a TimeUnitAmount, using plural rules for the units where available.
     41  *
     42  * <P>
     43  * Code Sample:
     44  * <pre>
     45  *   // create time unit amount instance - a combination of Number and time unit
     46  *   UErrorCode status = U_ZERO_ERROR;
     47  *   TimeUnitAmount* source = new TimeUnitAmount(2, TimeUnit::UTIMEUNIT_YEAR, status);
     48  *   // create time unit format instance
     49  *   TimeUnitFormat* format = new TimeUnitFormat(Locale("en"), status);
     50  *   // format a time unit amount
     51  *   UnicodeString formatted;
     52  *   Formattable formattable;
     53  *   if (U_SUCCESS(status)) {
     54  *       formattable.adoptObject(source);
     55  *       formatted = ((Format*)format)->format(formattable, formatted, status);
     56  *       Formattable result;
     57  *       ((Format*)format)->parseObject(formatted, result, status);
     58  *       if (U_SUCCESS(status)) {
     59  *           assert (result == formattable);
     60  *       }
     61  *   }
     62  * </pre>
     63  *
     64  * <P>
     65  * @see TimeUnitAmount
     66  * @see TimeUnitFormat
     67  * @draft ICU 4.2
     68  */
     69 class U_I18N_API TimeUnitFormat: public MeasureFormat {
     70 public:
     71 
     72     /**
     73      * Constants for various styles.
     74      * There are 2 styles: full name and abbreviated name.
     75      * For example, for English, the full name for hour duration is "3 hours",
     76      * and the abbreviated name is "3 hrs".
     77      * @draft ICU 4.2
     78      */
     79     enum EStyle {
     80         kFull = 0,
     81         kAbbreviate = 1,
     82         kTotal = kAbbreviate + 1
     83     };
     84 
     85     /**
     86      * Create TimeUnitFormat with default locale, and full name style.
     87      * Use setLocale and/or setFormat to modify.
     88      * @stable ICU 4.2
     89      */
     90     TimeUnitFormat(UErrorCode& status);
     91 
     92     /**
     93      * Create TimeUnitFormat given locale, and full name style.
     94      * @stable ICU 4.2
     95      */
     96     TimeUnitFormat(const Locale& locale, UErrorCode& status);
     97 
     98     /**
     99      * Create TimeUnitFormat given locale and style.
    100      * @draft ICU 4.2
    101      */
    102     TimeUnitFormat(const Locale& locale, EStyle style, UErrorCode& status);
    103 
    104     /**
    105      * Copy constructor.
    106      * @stable ICU 4.2
    107      */
    108     TimeUnitFormat(const TimeUnitFormat&);
    109 
    110     /**
    111      * deconstructor
    112      * @stable ICU 4.2
    113      */
    114     virtual ~TimeUnitFormat();
    115 
    116     /**
    117      * Clone this Format object polymorphically. The caller owns the result and
    118      * should delete it when done.
    119      * @return    A copy of the object.
    120      * @stable ICU 4.2
    121      */
    122     virtual Format* clone(void) const;
    123 
    124     /**
    125      * Assignment operator
    126      * @stable ICU 4.2
    127      */
    128     TimeUnitFormat& operator=(const TimeUnitFormat& other);
    129 
    130 
    131     /**
    132      * Return true if the given Format objects are semantically equal. Objects
    133      * of different subclasses are considered unequal.
    134      * @param other    the object to be compared with.
    135      * @return         true if the given Format objects are semantically equal.
    136      * @stable ICU 4.2
    137      */
    138     virtual UBool operator==(const Format& other) const;
    139 
    140     /**
    141      * Return true if the given Format objects are not semantically equal.
    142      * Objects of different subclasses are considered unequal.
    143      * @param other the object to be compared with.
    144      * @return      true if the given Format objects are not semantically equal.
    145      * @stable ICU 4.2
    146      */
    147     UBool operator!=(const Format& other) const;
    148 
    149     /**
    150      * Set the locale used for formatting or parsing.
    151      * @param locale  the locale to be set
    152      * @param status  output param set to success/failure code on exit
    153      * @stable ICU 4.2
    154      */
    155     void setLocale(const Locale& locale, UErrorCode& status);
    156 
    157 
    158     /**
    159      * Set the number format used for formatting or parsing.
    160      * @param format  the number formatter to be set
    161      * @param status  output param set to success/failure code on exit
    162      * @stable ICU 4.2
    163      */
    164     void setNumberFormat(const NumberFormat& format, UErrorCode& status);
    165 
    166 
    167     using MeasureFormat::format;
    168 
    169     /**
    170      * Format a TimeUnitAmount.
    171      * If the formattable object is not a time unit amount object,
    172      * or the number in time unit amount is not a double type or long type
    173      * numeric, it returns a failing status: U_ILLEGAL_ARGUMENT_ERROR.
    174      * @see Format#format(const Formattable&, UnicodeString&, FieldPosition&,  UErrorCode&) const
    175      * @stable ICU 4.2
    176      */
    177     virtual UnicodeString& format(const Formattable& obj,
    178                                   UnicodeString& toAppendTo,
    179                                   FieldPosition& pos,
    180                                   UErrorCode& status) const;
    181 
    182     /**
    183      * Parse a TimeUnitAmount.
    184      * @see Format#parseObject(const UnicodeString&, Formattable&, ParsePosition&) const;
    185      * @stable ICU 4.2
    186      */
    187     virtual void parseObject(const UnicodeString& source,
    188                              Formattable& result,
    189                              ParsePosition& pos) const;
    190 
    191     /**
    192      * Return the class ID for this class. This is useful only for comparing to
    193      * a return value from getDynamicClassID(). For example:
    194      * <pre>
    195      * .   Base* polymorphic_pointer = createPolymorphicObject();
    196      * .   if (polymorphic_pointer->getDynamicClassID() ==
    197      * .       erived::getStaticClassID()) ...
    198      * </pre>
    199      * @return          The class ID for all objects of this class.
    200      * @stable ICU 4.2
    201      */
    202     static UClassID U_EXPORT2 getStaticClassID(void);
    203 
    204     /**
    205      * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. This
    206      * method is to implement a simple version of RTTI, since not all C++
    207      * compilers support genuine RTTI. Polymorphic operator==() and clone()
    208      * methods call this method.
    209      *
    210      * @return          The class ID for this object. All objects of a
    211      *                  given class have the same class ID.  Objects of
    212      *                  other classes have different class IDs.
    213      * @stable ICU 4.2
    214      */
    215     virtual UClassID getDynamicClassID(void) const;
    216 
    217 private:
    218     NumberFormat* fNumberFormat;
    219     Locale        fLocale;
    220     Hashtable*    fTimeUnitToCountToPatterns[TimeUnit::UTIMEUNIT_FIELD_COUNT];
    221     PluralRules*  fPluralRules;
    222     EStyle           fStyle;
    223 
    224     void create(const Locale& locale, EStyle style, UErrorCode& status);
    225 
    226     // it might actually be simpler to make them Decimal Formats later.
    227     // initialize all private data members
    228     void setup(UErrorCode& status);
    229 
    230     // initialize data member without fill in data for fTimeUnitToCountToPattern
    231     void initDataMembers(UErrorCode& status);
    232 
    233     // initialize fTimeUnitToCountToPatterns from current locale's resource.
    234     void readFromCurrentLocale(EStyle style, const char* key, UErrorCode& status);
    235 
    236     // check completeness of fTimeUnitToCountToPatterns against all time units,
    237     // and all plural rules, fill in fallback as necessary.
    238     void checkConsistency(EStyle style, const char* key, UErrorCode& status);
    239 
    240     // fill in fTimeUnitToCountToPatterns from locale fall-back chain
    241     void searchInLocaleChain(EStyle style, const char* key,
    242                              TimeUnit::UTimeUnitFields field, const char*,
    243                              const char*, Hashtable*, UErrorCode&);
    244 
    245     // initialize hash table
    246     Hashtable* initHash(UErrorCode& status);
    247 
    248     // delete hash table
    249     void deleteHash(Hashtable* htable);
    250 
    251     // copy hash table
    252     void copyHash(const Hashtable* source, Hashtable* target, UErrorCode& status);
    253     // get time unit name, such as "year", from time unit field enum, such as
    254     // UTIMEUNIT_YEAR.
    255     static const char* getTimeUnitName(TimeUnit::UTimeUnitFields field, UErrorCode& status);
    256 };
    257 
    258 
    259 
    260 inline UBool
    261 TimeUnitFormat::operator!=(const Format& other) const  {
    262     return !operator==(other);
    263 }
    264 
    265 
    266 
    267 U_NAMESPACE_END
    268 
    269 #endif /* #if !UCONFIG_NO_FORMATTING */
    270 
    271 #endif // __TMUTFMT_H__
    272 //eof
    273