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) 1997-2016, International Business Machines Corporation and
      6 * others. All Rights Reserved.
      7 *******************************************************************************
      8 *
      9 * File FMTABLE.CPP
     10 *
     11 * Modification History:
     12 *
     13 *   Date        Name        Description
     14 *   03/25/97    clhuang     Initial Implementation.
     15 ********************************************************************************
     16 */
     17 
     18 #include "unicode/utypes.h"
     19 
     20 #if !UCONFIG_NO_FORMATTING
     21 
     22 #include <math.h>
     23 #include "unicode/fmtable.h"
     24 #include "unicode/ustring.h"
     25 #include "unicode/measure.h"
     26 #include "unicode/curramt.h"
     27 #include "unicode/uformattable.h"
     28 #include "charstr.h"
     29 #include "cmemory.h"
     30 #include "cstring.h"
     31 #include "decNumber.h"
     32 #include "digitlst.h"
     33 #include "fmtableimp.h"
     34 
     35 // *****************************************************************************
     36 // class Formattable
     37 // *****************************************************************************
     38 
     39 U_NAMESPACE_BEGIN
     40 
     41 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Formattable)
     42 
     43 
     44 //-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
     45 
     46 // NOTE: As of 3.0, there are limitations to the UObject API.  It does
     47 // not (yet) support cloning, operator=, nor operator==.  To
     48 // work around this, I implement some simple inlines here.  Later
     49 // these can be modified or removed.  [alan]
     50 
     51 // NOTE: These inlines assume that all fObjects are in fact instances
     52 // of the Measure class, which is true as of 3.0.  [alan]
     53 
     54 // Return TRUE if *a == *b.
     55 static inline UBool objectEquals(const UObject* a, const UObject* b) {
     56     // LATER: return *a == *b;
     57     return *((const Measure*) a) == *((const Measure*) b);
     58 }
     59 
     60 // Return a clone of *a.
     61 static inline UObject* objectClone(const UObject* a) {
     62     // LATER: return a->clone();
     63     return ((const Measure*) a)->clone();
     64 }
     65 
     66 // Return TRUE if *a is an instance of Measure.
     67 static inline UBool instanceOfMeasure(const UObject* a) {
     68     return dynamic_cast<const Measure*>(a) != NULL;
     69 }
     70 
     71 /**
     72  * Creates a new Formattable array and copies the values from the specified
     73  * original.
     74  * @param array the original array
     75  * @param count the original array count
     76  * @return the new Formattable array.
     77  */
     78 static Formattable* createArrayCopy(const Formattable* array, int32_t count) {
     79     Formattable *result = new Formattable[count];
     80     if (result != NULL) {
     81         for (int32_t i=0; i<count; ++i)
     82             result[i] = array[i]; // Don't memcpy!
     83     }
     84     return result;
     85 }
     86 
     87 //-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
     88 
     89 /**
     90  * Set 'ec' to 'err' only if 'ec' is not already set to a failing UErrorCode.
     91  */
     92 static void setError(UErrorCode& ec, UErrorCode err) {
     93     if (U_SUCCESS(ec)) {
     94         ec = err;
     95     }
     96 }
     97 
     98 //
     99 //  Common initialization code, shared by constructors.
    100 //  Put everything into a known state.
    101 //
    102 void  Formattable::init() {
    103     fValue.fInt64 = 0;
    104     fType = kLong;
    105     fDecimalStr = NULL;
    106     fDecimalNum = NULL;
    107     fBogus.setToBogus();
    108 }
    109 
    110 // -------------------------------------
    111 // default constructor.
    112 // Creates a formattable object with a long value 0.
    113 
    114 Formattable::Formattable() {
    115     init();
    116 }
    117 
    118 // -------------------------------------
    119 // Creates a formattable object with a Date instance.
    120 
    121 Formattable::Formattable(UDate date, ISDATE /*isDate*/)
    122 {
    123     init();
    124     fType = kDate;
    125     fValue.fDate = date;
    126 }
    127 
    128 // -------------------------------------
    129 // Creates a formattable object with a double value.
    130 
    131 Formattable::Formattable(double value)
    132 {
    133     init();
    134     fType = kDouble;
    135     fValue.fDouble = value;
    136 }
    137 
    138 // -------------------------------------
    139 // Creates a formattable object with an int32_t value.
    140 
    141 Formattable::Formattable(int32_t value)
    142 {
    143     init();
    144     fValue.fInt64 = value;
    145 }
    146 
    147 // -------------------------------------
    148 // Creates a formattable object with an int64_t value.
    149 
    150 Formattable::Formattable(int64_t value)
    151 {
    152     init();
    153     fType = kInt64;
    154     fValue.fInt64 = value;
    155 }
    156 
    157 // -------------------------------------
    158 // Creates a formattable object with a decimal number value from a string.
    159 
    160 Formattable::Formattable(StringPiece number, UErrorCode &status) {
    161     init();
    162     setDecimalNumber(number, status);
    163 }
    164 
    165 
    166 // -------------------------------------
    167 // Creates a formattable object with a UnicodeString instance.
    168 
    169 Formattable::Formattable(const UnicodeString& stringToCopy)
    170 {
    171     init();
    172     fType = kString;
    173     fValue.fString = new UnicodeString(stringToCopy);
    174 }
    175 
    176 // -------------------------------------
    177 // Creates a formattable object with a UnicodeString* value.
    178 // (adopting symantics)
    179 
    180 Formattable::Formattable(UnicodeString* stringToAdopt)
    181 {
    182     init();
    183     fType = kString;
    184     fValue.fString = stringToAdopt;
    185 }
    186 
    187 Formattable::Formattable(UObject* objectToAdopt)
    188 {
    189     init();
    190     fType = kObject;
    191     fValue.fObject = objectToAdopt;
    192 }
    193 
    194 // -------------------------------------
    195 
    196 Formattable::Formattable(const Formattable* arrayToCopy, int32_t count)
    197     :   UObject(), fType(kArray)
    198 {
    199     init();
    200     fType = kArray;
    201     fValue.fArrayAndCount.fArray = createArrayCopy(arrayToCopy, count);
    202     fValue.fArrayAndCount.fCount = count;
    203 }
    204 
    205 // -------------------------------------
    206 // copy constructor
    207 
    208 
    209 Formattable::Formattable(const Formattable &source)
    210      :  UObject(*this)
    211 {
    212     init();
    213     *this = source;
    214 }
    215 
    216 // -------------------------------------
    217 // assignment operator
    218 
    219 Formattable&
    220 Formattable::operator=(const Formattable& source)
    221 {
    222     if (this != &source)
    223     {
    224         // Disposes the current formattable value/setting.
    225         dispose();
    226 
    227         // Sets the correct data type for this value.
    228         fType = source.fType;
    229         switch (fType)
    230         {
    231         case kArray:
    232             // Sets each element in the array one by one and records the array count.
    233             fValue.fArrayAndCount.fCount = source.fValue.fArrayAndCount.fCount;
    234             fValue.fArrayAndCount.fArray = createArrayCopy(source.fValue.fArrayAndCount.fArray,
    235                                                            source.fValue.fArrayAndCount.fCount);
    236             break;
    237         case kString:
    238             // Sets the string value.
    239             fValue.fString = new UnicodeString(*source.fValue.fString);
    240             break;
    241         case kDouble:
    242             // Sets the double value.
    243             fValue.fDouble = source.fValue.fDouble;
    244             break;
    245         case kLong:
    246         case kInt64:
    247             // Sets the long value.
    248             fValue.fInt64 = source.fValue.fInt64;
    249             break;
    250         case kDate:
    251             // Sets the Date value.
    252             fValue.fDate = source.fValue.fDate;
    253             break;
    254         case kObject:
    255             fValue.fObject = objectClone(source.fValue.fObject);
    256             break;
    257         }
    258 
    259         UErrorCode status = U_ZERO_ERROR;
    260         if (source.fDecimalNum != NULL) {
    261           fDecimalNum = new DigitList(*source.fDecimalNum); // TODO: use internal digit list
    262         }
    263         if (source.fDecimalStr != NULL) {
    264             fDecimalStr = new CharString(*source.fDecimalStr, status);
    265             if (U_FAILURE(status)) {
    266                 delete fDecimalStr;
    267                 fDecimalStr = NULL;
    268             }
    269         }
    270     }
    271     return *this;
    272 }
    273 
    274 // -------------------------------------
    275 
    276 UBool
    277 Formattable::operator==(const Formattable& that) const
    278 {
    279     int32_t i;
    280 
    281     if (this == &that) return TRUE;
    282 
    283     // Returns FALSE if the data types are different.
    284     if (fType != that.fType) return FALSE;
    285 
    286     // Compares the actual data values.
    287     UBool equal = TRUE;
    288     switch (fType) {
    289     case kDate:
    290         equal = (fValue.fDate == that.fValue.fDate);
    291         break;
    292     case kDouble:
    293         equal = (fValue.fDouble == that.fValue.fDouble);
    294         break;
    295     case kLong:
    296     case kInt64:
    297         equal = (fValue.fInt64 == that.fValue.fInt64);
    298         break;
    299     case kString:
    300         equal = (*(fValue.fString) == *(that.fValue.fString));
    301         break;
    302     case kArray:
    303         if (fValue.fArrayAndCount.fCount != that.fValue.fArrayAndCount.fCount) {
    304             equal = FALSE;
    305             break;
    306         }
    307         // Checks each element for equality.
    308         for (i=0; i<fValue.fArrayAndCount.fCount; ++i) {
    309             if (fValue.fArrayAndCount.fArray[i] != that.fValue.fArrayAndCount.fArray[i]) {
    310                 equal = FALSE;
    311                 break;
    312             }
    313         }
    314         break;
    315     case kObject:
    316         if (fValue.fObject == NULL || that.fValue.fObject == NULL) {
    317             equal = FALSE;
    318         } else {
    319             equal = objectEquals(fValue.fObject, that.fValue.fObject);
    320         }
    321         break;
    322     }
    323 
    324     // TODO:  compare digit lists if numeric.
    325     return equal;
    326 }
    327 
    328 // -------------------------------------
    329 
    330 Formattable::~Formattable()
    331 {
    332     dispose();
    333 }
    334 
    335 // -------------------------------------
    336 
    337 void Formattable::dispose()
    338 {
    339     // Deletes the data value if necessary.
    340     switch (fType) {
    341     case kString:
    342         delete fValue.fString;
    343         break;
    344     case kArray:
    345         delete[] fValue.fArrayAndCount.fArray;
    346         break;
    347     case kObject:
    348         delete fValue.fObject;
    349         break;
    350     default:
    351         break;
    352     }
    353 
    354     fType = kLong;
    355     fValue.fInt64 = 0;
    356 
    357     delete fDecimalStr;
    358     fDecimalStr = NULL;
    359 
    360     FmtStackData *stackData = (FmtStackData*)fStackData;
    361     if(fDecimalNum != &(stackData->stackDecimalNum)) {
    362       delete fDecimalNum;
    363     } else {
    364       fDecimalNum->~DigitList(); // destruct, don't deallocate
    365     }
    366     fDecimalNum = NULL;
    367 }
    368 
    369 Formattable *
    370 Formattable::clone() const {
    371     return new Formattable(*this);
    372 }
    373 
    374 // -------------------------------------
    375 // Gets the data type of this Formattable object.
    376 Formattable::Type
    377 Formattable::getType() const
    378 {
    379     return fType;
    380 }
    381 
    382 UBool
    383 Formattable::isNumeric() const {
    384     switch (fType) {
    385     case kDouble:
    386     case kLong:
    387     case kInt64:
    388         return TRUE;
    389     default:
    390         return FALSE;
    391     }
    392 }
    393 
    394 // -------------------------------------
    395 int32_t
    396 //Formattable::getLong(UErrorCode* status) const
    397 Formattable::getLong(UErrorCode& status) const
    398 {
    399     if (U_FAILURE(status)) {
    400         return 0;
    401     }
    402 
    403     switch (fType) {
    404     case Formattable::kLong:
    405         return (int32_t)fValue.fInt64;
    406     case Formattable::kInt64:
    407         if (fValue.fInt64 > INT32_MAX) {
    408             status = U_INVALID_FORMAT_ERROR;
    409             return INT32_MAX;
    410         } else if (fValue.fInt64 < INT32_MIN) {
    411             status = U_INVALID_FORMAT_ERROR;
    412             return INT32_MIN;
    413         } else {
    414             return (int32_t)fValue.fInt64;
    415         }
    416     case Formattable::kDouble:
    417         if (fValue.fDouble > INT32_MAX) {
    418             status = U_INVALID_FORMAT_ERROR;
    419             return INT32_MAX;
    420         } else if (fValue.fDouble < INT32_MIN) {
    421             status = U_INVALID_FORMAT_ERROR;
    422             return INT32_MIN;
    423         } else {
    424             return (int32_t)fValue.fDouble; // loses fraction
    425         }
    426     case Formattable::kObject:
    427         if (fValue.fObject == NULL) {
    428             status = U_MEMORY_ALLOCATION_ERROR;
    429             return 0;
    430         }
    431         // TODO Later replace this with instanceof call
    432         if (instanceOfMeasure(fValue.fObject)) {
    433             return ((const Measure*) fValue.fObject)->
    434                 getNumber().getLong(status);
    435         }
    436         U_FALLTHROUGH;
    437     default:
    438         status = U_INVALID_FORMAT_ERROR;
    439         return 0;
    440     }
    441 }
    442 
    443 // -------------------------------------
    444 // Maximum int that can be represented exactly in a double.  (53 bits)
    445 //    Larger ints may be rounded to a near-by value as not all are representable.
    446 // TODO:  move this constant elsewhere, possibly configure it for different
    447 //        floating point formats, if any non-standard ones are still in use.
    448 static const int64_t U_DOUBLE_MAX_EXACT_INT = 9007199254740992LL;
    449 
    450 int64_t
    451 Formattable::getInt64(UErrorCode& status) const
    452 {
    453     if (U_FAILURE(status)) {
    454         return 0;
    455     }
    456 
    457     switch (fType) {
    458     case Formattable::kLong:
    459     case Formattable::kInt64:
    460         return fValue.fInt64;
    461     case Formattable::kDouble:
    462         if (fValue.fDouble > (double)U_INT64_MAX) {
    463             status = U_INVALID_FORMAT_ERROR;
    464             return U_INT64_MAX;
    465         } else if (fValue.fDouble < (double)U_INT64_MIN) {
    466             status = U_INVALID_FORMAT_ERROR;
    467             return U_INT64_MIN;
    468         } else if (fabs(fValue.fDouble) > U_DOUBLE_MAX_EXACT_INT && fDecimalNum != NULL) {
    469             int64_t val = fDecimalNum->getInt64();
    470             if (val != 0) {
    471                 return val;
    472             } else {
    473                 status = U_INVALID_FORMAT_ERROR;
    474                 return fValue.fDouble > 0 ? U_INT64_MAX : U_INT64_MIN;
    475             }
    476         } else {
    477             return (int64_t)fValue.fDouble;
    478         }
    479     case Formattable::kObject:
    480         if (fValue.fObject == NULL) {
    481             status = U_MEMORY_ALLOCATION_ERROR;
    482             return 0;
    483         }
    484         if (instanceOfMeasure(fValue.fObject)) {
    485             return ((const Measure*) fValue.fObject)->
    486                 getNumber().getInt64(status);
    487         }
    488         U_FALLTHROUGH;
    489     default:
    490         status = U_INVALID_FORMAT_ERROR;
    491         return 0;
    492     }
    493 }
    494 
    495 // -------------------------------------
    496 double
    497 Formattable::getDouble(UErrorCode& status) const
    498 {
    499     if (U_FAILURE(status)) {
    500         return 0;
    501     }
    502 
    503     switch (fType) {
    504     case Formattable::kLong:
    505     case Formattable::kInt64: // loses precision
    506         return (double)fValue.fInt64;
    507     case Formattable::kDouble:
    508         return fValue.fDouble;
    509     case Formattable::kObject:
    510         if (fValue.fObject == NULL) {
    511             status = U_MEMORY_ALLOCATION_ERROR;
    512             return 0;
    513         }
    514         // TODO Later replace this with instanceof call
    515         if (instanceOfMeasure(fValue.fObject)) {
    516             return ((const Measure*) fValue.fObject)->
    517                 getNumber().getDouble(status);
    518         }
    519         U_FALLTHROUGH;
    520     default:
    521         status = U_INVALID_FORMAT_ERROR;
    522         return 0;
    523     }
    524 }
    525 
    526 const UObject*
    527 Formattable::getObject() const {
    528     return (fType == kObject) ? fValue.fObject : NULL;
    529 }
    530 
    531 // -------------------------------------
    532 // Sets the value to a double value d.
    533 
    534 void
    535 Formattable::setDouble(double d)
    536 {
    537     dispose();
    538     fType = kDouble;
    539     fValue.fDouble = d;
    540 }
    541 
    542 // -------------------------------------
    543 // Sets the value to a long value l.
    544 
    545 void
    546 Formattable::setLong(int32_t l)
    547 {
    548     dispose();
    549     fType = kLong;
    550     fValue.fInt64 = l;
    551 }
    552 
    553 // -------------------------------------
    554 // Sets the value to an int64 value ll.
    555 
    556 void
    557 Formattable::setInt64(int64_t ll)
    558 {
    559     dispose();
    560     fType = kInt64;
    561     fValue.fInt64 = ll;
    562 }
    563 
    564 // -------------------------------------
    565 // Sets the value to a Date instance d.
    566 
    567 void
    568 Formattable::setDate(UDate d)
    569 {
    570     dispose();
    571     fType = kDate;
    572     fValue.fDate = d;
    573 }
    574 
    575 // -------------------------------------
    576 // Sets the value to a string value stringToCopy.
    577 
    578 void
    579 Formattable::setString(const UnicodeString& stringToCopy)
    580 {
    581     dispose();
    582     fType = kString;
    583     fValue.fString = new UnicodeString(stringToCopy);
    584 }
    585 
    586 // -------------------------------------
    587 // Sets the value to an array of Formattable objects.
    588 
    589 void
    590 Formattable::setArray(const Formattable* array, int32_t count)
    591 {
    592     dispose();
    593     fType = kArray;
    594     fValue.fArrayAndCount.fArray = createArrayCopy(array, count);
    595     fValue.fArrayAndCount.fCount = count;
    596 }
    597 
    598 // -------------------------------------
    599 // Adopts the stringToAdopt value.
    600 
    601 void
    602 Formattable::adoptString(UnicodeString* stringToAdopt)
    603 {
    604     dispose();
    605     fType = kString;
    606     fValue.fString = stringToAdopt;
    607 }
    608 
    609 // -------------------------------------
    610 // Adopts the array value and its count.
    611 
    612 void
    613 Formattable::adoptArray(Formattable* array, int32_t count)
    614 {
    615     dispose();
    616     fType = kArray;
    617     fValue.fArrayAndCount.fArray = array;
    618     fValue.fArrayAndCount.fCount = count;
    619 }
    620 
    621 void
    622 Formattable::adoptObject(UObject* objectToAdopt) {
    623     dispose();
    624     fType = kObject;
    625     fValue.fObject = objectToAdopt;
    626 }
    627 
    628 // -------------------------------------
    629 UnicodeString&
    630 Formattable::getString(UnicodeString& result, UErrorCode& status) const
    631 {
    632     if (fType != kString) {
    633         setError(status, U_INVALID_FORMAT_ERROR);
    634         result.setToBogus();
    635     } else {
    636         if (fValue.fString == NULL) {
    637             setError(status, U_MEMORY_ALLOCATION_ERROR);
    638         } else {
    639             result = *fValue.fString;
    640         }
    641     }
    642     return result;
    643 }
    644 
    645 // -------------------------------------
    646 const UnicodeString&
    647 Formattable::getString(UErrorCode& status) const
    648 {
    649     if (fType != kString) {
    650         setError(status, U_INVALID_FORMAT_ERROR);
    651         return *getBogus();
    652     }
    653     if (fValue.fString == NULL) {
    654         setError(status, U_MEMORY_ALLOCATION_ERROR);
    655         return *getBogus();
    656     }
    657     return *fValue.fString;
    658 }
    659 
    660 // -------------------------------------
    661 UnicodeString&
    662 Formattable::getString(UErrorCode& status)
    663 {
    664     if (fType != kString) {
    665         setError(status, U_INVALID_FORMAT_ERROR);
    666         return *getBogus();
    667     }
    668     if (fValue.fString == NULL) {
    669     	setError(status, U_MEMORY_ALLOCATION_ERROR);
    670     	return *getBogus();
    671     }
    672     return *fValue.fString;
    673 }
    674 
    675 // -------------------------------------
    676 const Formattable*
    677 Formattable::getArray(int32_t& count, UErrorCode& status) const
    678 {
    679     if (fType != kArray) {
    680         setError(status, U_INVALID_FORMAT_ERROR);
    681         count = 0;
    682         return NULL;
    683     }
    684     count = fValue.fArrayAndCount.fCount;
    685     return fValue.fArrayAndCount.fArray;
    686 }
    687 
    688 // -------------------------------------
    689 // Gets the bogus string, ensures mondo bogosity.
    690 
    691 UnicodeString*
    692 Formattable::getBogus() const
    693 {
    694     return (UnicodeString*)&fBogus; /* cast away const :-( */
    695 }
    696 
    697 
    698 // --------------------------------------
    699 StringPiece Formattable::getDecimalNumber(UErrorCode &status) {
    700     if (U_FAILURE(status)) {
    701         return "";
    702     }
    703     if (fDecimalStr != NULL) {
    704       return fDecimalStr->toStringPiece();
    705     }
    706 
    707     CharString *decimalStr = internalGetCharString(status);
    708     if(decimalStr == NULL) {
    709       return ""; // getDecimalNumber returns "" for error cases
    710     } else {
    711       return decimalStr->toStringPiece();
    712     }
    713 }
    714 
    715 CharString *Formattable::internalGetCharString(UErrorCode &status) {
    716     if(fDecimalStr == NULL) {
    717       if (fDecimalNum == NULL) {
    718         // No decimal number for the formattable yet.  Which means the value was
    719         // set directly by the user as an int, int64 or double.  If the value came
    720         // from parsing, or from the user setting a decimal number, fDecimalNum
    721         // would already be set.
    722         //
    723         fDecimalNum = new DigitList; // TODO: use internal digit list
    724         if (fDecimalNum == NULL) {
    725           status = U_MEMORY_ALLOCATION_ERROR;
    726           return NULL;
    727         }
    728 
    729         switch (fType) {
    730         case kDouble:
    731           fDecimalNum->set(this->getDouble());
    732           break;
    733         case kLong:
    734           fDecimalNum->set(this->getLong());
    735           break;
    736         case kInt64:
    737           fDecimalNum->set(this->getInt64());
    738           break;
    739         default:
    740           // The formattable's value is not a numeric type.
    741           status = U_INVALID_STATE_ERROR;
    742           return NULL;
    743         }
    744       }
    745 
    746       fDecimalStr = new CharString;
    747       if (fDecimalStr == NULL) {
    748         status = U_MEMORY_ALLOCATION_ERROR;
    749         return NULL;
    750       }
    751       fDecimalNum->getDecimal(*fDecimalStr, status);
    752     }
    753     return fDecimalStr;
    754 }
    755 
    756 
    757 DigitList *
    758 Formattable::getInternalDigitList() {
    759   FmtStackData *stackData = (FmtStackData*)fStackData;
    760   if(fDecimalNum != &(stackData->stackDecimalNum)) {
    761     delete fDecimalNum;
    762     fDecimalNum = new (&(stackData->stackDecimalNum), kOnStack) DigitList();
    763   } else {
    764     fDecimalNum->clear();
    765   }
    766   return fDecimalNum;
    767 }
    768 
    769 // ---------------------------------------
    770 void
    771 Formattable::adoptDigitList(DigitList *dl) {
    772   if(fDecimalNum==dl) {
    773     fDecimalNum = NULL; // don't delete
    774   }
    775   dispose();
    776 
    777   fDecimalNum = dl;
    778 
    779   if(dl==NULL) { // allow adoptDigitList(NULL) to clear
    780     return;
    781   }
    782 
    783     // Set the value into the Union of simple type values.
    784     // Cannot use the set() functions because they would delete the fDecimalNum value,
    785 
    786     if (fDecimalNum->fitsIntoLong(FALSE)) {
    787         fType = kLong;
    788         fValue.fInt64 = fDecimalNum->getLong();
    789     } else if (fDecimalNum->fitsIntoInt64(FALSE)) {
    790         fType = kInt64;
    791         fValue.fInt64 = fDecimalNum->getInt64();
    792     } else {
    793         fType = kDouble;
    794         fValue.fDouble = fDecimalNum->getDouble();
    795     }
    796 }
    797 
    798 
    799 // ---------------------------------------
    800 void
    801 Formattable::setDecimalNumber(StringPiece numberString, UErrorCode &status) {
    802     if (U_FAILURE(status)) {
    803         return;
    804     }
    805     dispose();
    806 
    807     // Copy the input string and nul-terminate it.
    808     //    The decNumber library requires nul-terminated input.  StringPiece input
    809     //    is not guaranteed nul-terminated.  Too bad.
    810     //    CharString automatically adds the nul.
    811     DigitList *dnum = new DigitList(); // TODO: use getInternalDigitList
    812     if (dnum == NULL) {
    813         status = U_MEMORY_ALLOCATION_ERROR;
    814         return;
    815     }
    816     dnum->set(CharString(numberString, status).toStringPiece(), status);
    817     if (U_FAILURE(status)) {
    818         delete dnum;
    819         return;   // String didn't contain a decimal number.
    820     }
    821     adoptDigitList(dnum);
    822 
    823     // Note that we do not hang on to the caller's input string.
    824     // If we are asked for the string, we will regenerate one from fDecimalNum.
    825 }
    826 
    827 #if 0
    828 //----------------------------------------------------
    829 // console I/O
    830 //----------------------------------------------------
    831 #ifdef _DEBUG
    832 
    833 #include <iostream>
    834 using namespace std;
    835 
    836 #include "unicode/datefmt.h"
    837 #include "unistrm.h"
    838 
    839 class FormattableStreamer /* not : public UObject because all methods are static */ {
    840 public:
    841     static void streamOut(ostream& stream, const Formattable& obj);
    842 
    843 private:
    844     FormattableStreamer() {} // private - forbid instantiation
    845 };
    846 
    847 // This is for debugging purposes only.  This will send a displayable
    848 // form of the Formattable object to the output stream.
    849 
    850 void
    851 FormattableStreamer::streamOut(ostream& stream, const Formattable& obj)
    852 {
    853     static DateFormat *defDateFormat = 0;
    854 
    855     UnicodeString buffer;
    856     switch(obj.getType()) {
    857         case Formattable::kDate :
    858             // Creates a DateFormat instance for formatting the
    859             // Date instance.
    860             if (defDateFormat == 0) {
    861                 defDateFormat = DateFormat::createInstance();
    862             }
    863             defDateFormat->format(obj.getDate(), buffer);
    864             stream << buffer;
    865             break;
    866         case Formattable::kDouble :
    867             // Output the double as is.
    868             stream << obj.getDouble() << 'D';
    869             break;
    870         case Formattable::kLong :
    871             // Output the double as is.
    872             stream << obj.getLong() << 'L';
    873             break;
    874         case Formattable::kString:
    875             // Output the double as is.  Please see UnicodeString console
    876             // I/O routine for more details.
    877             stream << '"' << obj.getString(buffer) << '"';
    878             break;
    879         case Formattable::kArray:
    880             int32_t i, count;
    881             const Formattable* array;
    882             array = obj.getArray(count);
    883             stream << '[';
    884             // Recursively calling the console I/O routine for each element in the array.
    885             for (i=0; i<count; ++i) {
    886                 FormattableStreamer::streamOut(stream, array[i]);
    887                 stream << ( (i==(count-1)) ? "" : ", " );
    888             }
    889             stream << ']';
    890             break;
    891         default:
    892             // Not a recognizable Formattable object.
    893             stream << "INVALID_Formattable";
    894     }
    895     stream.flush();
    896 }
    897 #endif
    898 
    899 #endif
    900 
    901 U_NAMESPACE_END
    902 
    903 /* ---- UFormattable implementation ---- */
    904 
    905 U_NAMESPACE_USE
    906 
    907 U_DRAFT UFormattable* U_EXPORT2
    908 ufmt_open(UErrorCode *status) {
    909   if( U_FAILURE(*status) ) {
    910     return NULL;
    911   }
    912   UFormattable *fmt = (new Formattable())->toUFormattable();
    913 
    914   if( fmt == NULL ) {
    915     *status = U_MEMORY_ALLOCATION_ERROR;
    916   }
    917   return fmt;
    918 }
    919 
    920 U_DRAFT void U_EXPORT2
    921 ufmt_close(UFormattable *fmt) {
    922   Formattable *obj = Formattable::fromUFormattable(fmt);
    923 
    924   delete obj;
    925 }
    926 
    927 U_INTERNAL UFormattableType U_EXPORT2
    928 ufmt_getType(const UFormattable *fmt, UErrorCode *status) {
    929   if(U_FAILURE(*status)) {
    930     return (UFormattableType)UFMT_COUNT;
    931   }
    932   const Formattable *obj = Formattable::fromUFormattable(fmt);
    933   return (UFormattableType)obj->getType();
    934 }
    935 
    936 
    937 U_INTERNAL UBool U_EXPORT2
    938 ufmt_isNumeric(const UFormattable *fmt) {
    939   const Formattable *obj = Formattable::fromUFormattable(fmt);
    940   return obj->isNumeric();
    941 }
    942 
    943 U_DRAFT UDate U_EXPORT2
    944 ufmt_getDate(const UFormattable *fmt, UErrorCode *status) {
    945   const Formattable *obj = Formattable::fromUFormattable(fmt);
    946 
    947   return obj->getDate(*status);
    948 }
    949 
    950 U_DRAFT double U_EXPORT2
    951 ufmt_getDouble(UFormattable *fmt, UErrorCode *status) {
    952   Formattable *obj = Formattable::fromUFormattable(fmt);
    953 
    954   return obj->getDouble(*status);
    955 }
    956 
    957 U_DRAFT int32_t U_EXPORT2
    958 ufmt_getLong(UFormattable *fmt, UErrorCode *status) {
    959   Formattable *obj = Formattable::fromUFormattable(fmt);
    960 
    961   return obj->getLong(*status);
    962 }
    963 
    964 
    965 U_DRAFT const void *U_EXPORT2
    966 ufmt_getObject(const UFormattable *fmt, UErrorCode *status) {
    967   const Formattable *obj = Formattable::fromUFormattable(fmt);
    968 
    969   const void *ret = obj->getObject();
    970   if( ret==NULL &&
    971       (obj->getType() != Formattable::kObject) &&
    972       U_SUCCESS( *status )) {
    973     *status = U_INVALID_FORMAT_ERROR;
    974   }
    975   return ret;
    976 }
    977 
    978 U_DRAFT const UChar* U_EXPORT2
    979 ufmt_getUChars(UFormattable *fmt, int32_t *len, UErrorCode *status) {
    980   Formattable *obj = Formattable::fromUFormattable(fmt);
    981 
    982   // avoid bogosity by checking the type first.
    983   if( obj->getType() != Formattable::kString ) {
    984     if( U_SUCCESS(*status) ){
    985       *status = U_INVALID_FORMAT_ERROR;
    986     }
    987     return NULL;
    988   }
    989 
    990   // This should return a valid string
    991   UnicodeString &str = obj->getString(*status);
    992   if( U_SUCCESS(*status) && len != NULL ) {
    993     *len = str.length();
    994   }
    995   return str.getTerminatedBuffer();
    996 }
    997 
    998 U_DRAFT int32_t U_EXPORT2
    999 ufmt_getArrayLength(const UFormattable* fmt, UErrorCode *status) {
   1000   const Formattable *obj = Formattable::fromUFormattable(fmt);
   1001 
   1002   int32_t count;
   1003   (void)obj->getArray(count, *status);
   1004   return count;
   1005 }
   1006 
   1007 U_DRAFT UFormattable * U_EXPORT2
   1008 ufmt_getArrayItemByIndex(UFormattable* fmt, int32_t n, UErrorCode *status) {
   1009   Formattable *obj = Formattable::fromUFormattable(fmt);
   1010   int32_t count;
   1011   (void)obj->getArray(count, *status);
   1012   if(U_FAILURE(*status)) {
   1013     return NULL;
   1014   } else if(n<0 || n>=count) {
   1015     setError(*status, U_INDEX_OUTOFBOUNDS_ERROR);
   1016     return NULL;
   1017   } else {
   1018     return (*obj)[n].toUFormattable(); // returns non-const Formattable
   1019   }
   1020 }
   1021 
   1022 U_DRAFT const char * U_EXPORT2
   1023 ufmt_getDecNumChars(UFormattable *fmt, int32_t *len, UErrorCode *status) {
   1024   if(U_FAILURE(*status)) {
   1025     return "";
   1026   }
   1027   Formattable *obj = Formattable::fromUFormattable(fmt);
   1028   CharString *charString = obj->internalGetCharString(*status);
   1029   if(U_FAILURE(*status)) {
   1030     return "";
   1031   }
   1032   if(charString == NULL) {
   1033     *status = U_MEMORY_ALLOCATION_ERROR;
   1034     return "";
   1035   } else {
   1036     if(len!=NULL) {
   1037       *len = charString->length();
   1038     }
   1039     return charString->data();
   1040   }
   1041 }
   1042 
   1043 U_DRAFT int64_t U_EXPORT2
   1044 ufmt_getInt64(UFormattable *fmt, UErrorCode *status) {
   1045   Formattable *obj = Formattable::fromUFormattable(fmt);
   1046   return obj->getInt64(*status);
   1047 }
   1048 
   1049 #endif /* #if !UCONFIG_NO_FORMATTING */
   1050 
   1051 //eof
   1052