Home | History | Annotate | Download | only in i18n
      1 /*
      2 *******************************************************************************
      3 * Copyright (C) 2015, International Business Machines Corporation and
      4 * others. All Rights Reserved.
      5 *******************************************************************************
      6 */
      7 
      8 #include "unicode/plurrule.h"
      9 #include "unicode/unistr.h"
     10 #include "unicode/utypes.h"
     11 
     12 #if !UCONFIG_NO_FORMATTING
     13 
     14 #include "digitformatter.h"
     15 #include "digitgrouping.h"
     16 #include "digitinterval.h"
     17 #include "digitlst.h"
     18 #include "precision.h"
     19 #include "plurrule_impl.h"
     20 #include "smallintformatter.h"
     21 #include "uassert.h"
     22 #include "valueformatter.h"
     23 #include "visibledigits.h"
     24 
     25 U_NAMESPACE_BEGIN
     26 
     27 ValueFormatter::~ValueFormatter() {}
     28 
     29 VisibleDigitsWithExponent &
     30 ValueFormatter::toVisibleDigitsWithExponent(
     31         int64_t value,
     32         VisibleDigitsWithExponent &digits,
     33         UErrorCode &status) const {
     34     switch (fType) {
     35     case kFixedDecimal:
     36         return fFixedPrecision->initVisibleDigitsWithExponent(
     37                 value, digits, status);
     38         break;
     39     case kScientificNotation:
     40         return fScientificPrecision->initVisibleDigitsWithExponent(
     41                 value, digits, status);
     42         break;
     43     default:
     44         U_ASSERT(FALSE);
     45         break;
     46     }
     47     return digits;
     48 }
     49 
     50 VisibleDigitsWithExponent &
     51 ValueFormatter::toVisibleDigitsWithExponent(
     52         DigitList &value,
     53         VisibleDigitsWithExponent &digits,
     54         UErrorCode &status) const {
     55     switch (fType) {
     56     case kFixedDecimal:
     57         return fFixedPrecision->initVisibleDigitsWithExponent(
     58                 value, digits, status);
     59         break;
     60     case kScientificNotation:
     61         return fScientificPrecision->initVisibleDigitsWithExponent(
     62                 value, digits, status);
     63         break;
     64     default:
     65         U_ASSERT(FALSE);
     66         break;
     67     }
     68     return digits;
     69 }
     70 
     71 static UBool isNoGrouping(
     72         const DigitGrouping &grouping,
     73         int32_t value,
     74         const FixedPrecision &precision) {
     75     IntDigitCountRange range(
     76             precision.fMin.getIntDigitCount(),
     77             precision.fMax.getIntDigitCount());
     78     return grouping.isNoGrouping(value, range);
     79 }
     80 
     81 UBool
     82 ValueFormatter::isFastFormattable(int32_t value) const {
     83     switch (fType) {
     84     case kFixedDecimal:
     85         {
     86             if (value == INT32_MIN) {
     87                 return FALSE;
     88             }
     89             if (value < 0) {
     90                 value = -value;
     91             }
     92             return fFixedPrecision->isFastFormattable() && fFixedOptions->isFastFormattable() && isNoGrouping(*fGrouping, value, *fFixedPrecision);
     93         }
     94     case kScientificNotation:
     95         return FALSE;
     96     default:
     97         U_ASSERT(FALSE);
     98         break;
     99     }
    100     return FALSE;
    101 }
    102 
    103 DigitList &
    104 ValueFormatter::round(DigitList &value, UErrorCode &status) const {
    105     if (value.isNaN() || value.isInfinite()) {
    106         return value;
    107     }
    108     switch (fType) {
    109     case kFixedDecimal:
    110         return fFixedPrecision->round(value, 0, status);
    111     case kScientificNotation:
    112         return fScientificPrecision->round(value, status);
    113     default:
    114         U_ASSERT(FALSE);
    115         break;
    116     }
    117     return value;
    118 }
    119 
    120 UnicodeString &
    121 ValueFormatter::formatInt32(
    122         int32_t value,
    123         FieldPositionHandler &handler,
    124         UnicodeString &appendTo) const {
    125     switch (fType) {
    126     case kFixedDecimal:
    127         {
    128             IntDigitCountRange range(
    129                     fFixedPrecision->fMin.getIntDigitCount(),
    130                     fFixedPrecision->fMax.getIntDigitCount());
    131             return fDigitFormatter->formatPositiveInt32(
    132                     value,
    133                     range,
    134                     handler,
    135                     appendTo);
    136         }
    137         break;
    138     case kScientificNotation:
    139     default:
    140         U_ASSERT(FALSE);
    141         break;
    142     }
    143     return appendTo;
    144 }
    145 
    146 UnicodeString &
    147 ValueFormatter::format(
    148         const VisibleDigitsWithExponent &value,
    149         FieldPositionHandler &handler,
    150         UnicodeString &appendTo) const {
    151     switch (fType) {
    152     case kFixedDecimal:
    153         return fDigitFormatter->format(
    154                 value.getMantissa(),
    155                 *fGrouping,
    156                 *fFixedOptions,
    157                 handler,
    158                 appendTo);
    159         break;
    160     case kScientificNotation:
    161         return fDigitFormatter->format(
    162                 value,
    163                 *fScientificOptions,
    164                 handler,
    165                 appendTo);
    166         break;
    167     default:
    168         U_ASSERT(FALSE);
    169         break;
    170     }
    171     return appendTo;
    172 }
    173 
    174 int32_t
    175 ValueFormatter::countChar32(const VisibleDigitsWithExponent &value) const {
    176     switch (fType) {
    177     case kFixedDecimal:
    178         return fDigitFormatter->countChar32(
    179                 value.getMantissa(),
    180                 *fGrouping,
    181                 *fFixedOptions);
    182         break;
    183     case kScientificNotation:
    184         return fDigitFormatter->countChar32(
    185                 value,
    186                 *fScientificOptions);
    187         break;
    188     default:
    189         U_ASSERT(FALSE);
    190         break;
    191     }
    192     return 0;
    193 }
    194 
    195 void
    196 ValueFormatter::prepareFixedDecimalFormatting(
    197         const DigitFormatter &formatter,
    198         const DigitGrouping &grouping,
    199         const FixedPrecision &precision,
    200         const DigitFormatterOptions &options) {
    201     fType = kFixedDecimal;
    202     fDigitFormatter = &formatter;
    203     fGrouping = &grouping;
    204     fFixedPrecision = &precision;
    205     fFixedOptions = &options;
    206 }
    207 
    208 void
    209 ValueFormatter::prepareScientificFormatting(
    210         const DigitFormatter &formatter,
    211         const ScientificPrecision &precision,
    212         const SciFormatterOptions &options) {
    213     fType = kScientificNotation;
    214     fDigitFormatter = &formatter;
    215     fScientificPrecision = &precision;
    216     fScientificOptions = &options;
    217 }
    218 
    219 U_NAMESPACE_END
    220 
    221 #endif /* !UCONFIG_NO_FORMATTING */
    222