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