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