]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/fmtable.cpp
ICU-511.25.tar.gz
[apple/icu.git] / icuSources / i18n / fmtable.cpp
index b28bf6a3f2b27d4fb38f16667689c17250fff993..274b3d782d069f3e1450efb866d2e32b496cb8f6 100644 (file)
@@ -1,6 +1,6 @@
 /*
 *******************************************************************************
-* Copyright (C) 1997-2011, International Business Machines Corporation and    *
+* Copyright (C) 1997-2012, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
@@ -36,6 +36,8 @@ U_NAMESPACE_BEGIN
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Formattable)
 
+#include "fmtableimp.h"
+
 //-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
 
 // NOTE: As of 3.0, there are limitations to the UObject API.  It does
@@ -253,7 +255,7 @@ Formattable::operator=(const Formattable& source)
 
         UErrorCode status = U_ZERO_ERROR;
         if (source.fDecimalNum != NULL) {
-            fDecimalNum = new DigitList(*source.fDecimalNum);
+          fDecimalNum = new DigitList(*source.fDecimalNum); // TODO: use internal digit list
         }
         if (source.fDecimalStr != NULL) {
             fDecimalStr = new CharString(*source.fDecimalStr, status);
@@ -348,9 +350,16 @@ void Formattable::dispose()
 
     fType = kLong;
     fValue.fInt64 = 0;
+
     delete fDecimalStr;
     fDecimalStr = NULL;
-    delete fDecimalNum;
+    
+    FmtStackData *stackData = (FmtStackData*)fStackData;
+    if(fDecimalNum != &(stackData->stackDecimalNum)) {
+      delete fDecimalNum;
+    } else {
+      fDecimalNum->~DigitList(); // destruct, don't deallocate
+    }
     fDecimalNum = NULL;
 }
 
@@ -695,7 +704,7 @@ StringPiece Formattable::getDecimalNumber(UErrorCode &status) {
         // from parsing, or from the user setting a decimal number, fDecimalNum
         // would already be set.
         //
-        fDecimalNum = new DigitList;
+      fDecimalNum = new DigitList; // TODO: use internal digit list
         if (fDecimalNum == NULL) {
             status = U_MEMORY_ALLOCATION_ERROR;
             return "";
@@ -729,13 +738,31 @@ StringPiece Formattable::getDecimalNumber(UErrorCode &status) {
 }
 
 
+DigitList *
+Formattable::getInternalDigitList() {
+  FmtStackData *stackData = (FmtStackData*)fStackData;
+  if(fDecimalNum != &(stackData->stackDecimalNum)) {
+    delete fDecimalNum;
+    fDecimalNum = new (&(stackData->stackDecimalNum), kOnStack) DigitList();
+  } else {
+    fDecimalNum->clear();
+  }
+  return fDecimalNum;
+}
 
 // ---------------------------------------
 void
 Formattable::adoptDigitList(DigitList *dl) {
-    dispose();
+  if(fDecimalNum==dl) {
+    fDecimalNum = NULL; // don't delete
+  }
+  dispose();
+
+  fDecimalNum = dl;
 
-    fDecimalNum = dl;
+  if(dl==NULL) { // allow adoptDigitList(NULL) to clear
+    return;
+  }
 
     // Set the value into the Union of simple type values.
     // Cannot use the set() functions because they would delete the fDecimalNum value,
@@ -765,7 +792,7 @@ Formattable::setDecimalNumber(const StringPiece &numberString, UErrorCode &statu
     //    The decNumber library requires nul-terminated input.  StringPiece input
     //    is not guaranteed nul-terminated.  Too bad.
     //    CharString automatically adds the nul.
-    DigitList *dnum = new DigitList();
+    DigitList *dnum = new DigitList(); // TODO: use getInternalDigitList
     if (dnum == NULL) {
         status = U_MEMORY_ALLOCATION_ERROR;
         return;