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