]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/decfmtst.cpp
ICU-400.37.tar.gz
[apple/icu.git] / icuSources / i18n / decfmtst.cpp
diff --git a/icuSources/i18n/decfmtst.cpp b/icuSources/i18n/decfmtst.cpp
new file mode 100644 (file)
index 0000000..573dcbf
--- /dev/null
@@ -0,0 +1,215 @@
+//
+//  decfmtst.h
+//
+//  Copyright (C) 20098, International Business Machines Corporation and others.
+//  All Rights Reserved.
+//
+//  This file contains the class DecimalFormatStaticSets
+//
+//  DecimalFormatStaticSets holds the UnicodeSets that are needed for lenient
+//  parsing of decimal and group separators.
+//
+#include "unicode/utypes.h"
+
+#include "unicode/unistr.h"
+#include "unicode/uniset.h"
+#include "unicode/uchar.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "uassert.h"
+#include "ucln_in.h"
+#include "umutex.h"
+
+#include "decfmtst.h"
+
+U_NAMESPACE_BEGIN
+
+
+//------------------------------------------------------------------------------
+//
+// Unicode Set pattern strings for all of the required constant sets.
+//               Initialized with hex values for portability to EBCDIC based machines.
+//                Really ugly, but there's no good way to avoid it.
+//
+//------------------------------------------------------------------------------
+
+static const UChar gDotEquivalentsPattern[] = {
+               // [       .    \u2024  \u3002  \uFE12  \uFE52  \uFF0E  \uFF61     ]
+               0x005B, 0x002E, 0x2024, 0x3002, 0xFE12, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
+
+static const UChar gCommaEquivalentsPattern[] = {
+               // [       ,    \u060C  \u066B  \u3001  \uFE10  \uFE11  \uFE50  \uFE51  \uFF0C  \uFF64    ]
+        0x005B, 0x002C, 0x060C, 0x066B, 0x3001, 0xFE10, 0xFE11, 0xFE50, 0xFE51, 0xFF0C, 0xFF64, 0x005D, 0x0000};
+
+static const UChar gOtherGroupingSeparatorsPattern[] = {
+               // [       \     SPACE     '      NBSP  \u066C  \u2000     -    \u200A  \u2018  \u2019  \u202F  \u205F  \u3000  \uFF07     ]
+        0x005B, 0x005C, 0x0020, 0x0027, 0x00A0, 0x066C, 0x2000, 0x002D, 0x200A, 0x2018, 0x2019, 0x202F, 0x205F, 0x3000, 0xFF07, 0x005D, 0x0000};
+
+static const UChar gStrictDotEquivalentsPattern[] = {
+               // [      .     \u2024  \uFE52  \uFF0E  \uFF61    ]
+        0x005B, 0x002E, 0x2024, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
+
+static const UChar gStrictCommaEquivalentsPattern[] = {
+               // [       ,    \u066B  \uFE10  \uFE50  \uFF0C     ]
+        0x005B, 0x002C, 0x066B, 0xFE10, 0xFE50, 0xFF0C, 0x005D, 0x0000};
+
+static const UChar gStrictOtherGroupingSeparatorsPattern[] = {
+               // [       \     SPACE     '      NBSP  \u066C  \u2000     -    \u200A  \u2018  \u2019  \u202F  \u205F  \u3000  \uFF07     ]
+        0x005B, 0x005C, 0x0020, 0x0027, 0x00A0, 0x066C, 0x2000, 0x002D, 0x200A, 0x2018, 0x2019, 0x202F, 0x205F, 0x3000, 0xFF07, 0x005D, 0x0000};
+
+
+DecimalFormatStaticSets *DecimalFormatStaticSets::gStaticSets = NULL;
+
+DecimalFormatStaticSets::DecimalFormatStaticSets(UErrorCode *status)
+: fDotEquivalents(NULL),
+  fCommaEquivalents(NULL),
+  fOtherGroupingSeparators(NULL),
+  fStrictDotEquivalents(NULL),
+  fStrictCommaEquivalents(NULL),
+  fStrictOtherGroupingSeparators(NULL),
+  fDefaultGroupingSeparators(NULL),
+  fStrictDefaultGroupingSeparators(NULL)
+{
+    fDotEquivalents                = new UnicodeSet(UnicodeString(TRUE, gDotEquivalentsPattern, -1),                *status);
+    fCommaEquivalents              = new UnicodeSet(UnicodeString(TRUE, gCommaEquivalentsPattern, -1),              *status);
+    fOtherGroupingSeparators       = new UnicodeSet(UnicodeString(TRUE, gOtherGroupingSeparatorsPattern, -1),       *status);
+    fStrictDotEquivalents          = new UnicodeSet(UnicodeString(TRUE, gStrictDotEquivalentsPattern, -1),          *status);
+    fStrictCommaEquivalents        = new UnicodeSet(UnicodeString(TRUE, gStrictCommaEquivalentsPattern, -1),        *status);
+    fStrictOtherGroupingSeparators = new UnicodeSet(UnicodeString(TRUE, gStrictOtherGroupingSeparatorsPattern, -1), *status);
+
+
+    fDefaultGroupingSeparators = new UnicodeSet(*fDotEquivalents);
+    fDefaultGroupingSeparators->addAll(*fCommaEquivalents);
+    fDefaultGroupingSeparators->addAll(*fOtherGroupingSeparators);
+
+    fStrictDefaultGroupingSeparators = new UnicodeSet(*fStrictDotEquivalents);
+    fStrictDefaultGroupingSeparators->addAll(*fStrictCommaEquivalents);
+    fStrictDefaultGroupingSeparators->addAll(*fStrictOtherGroupingSeparators);
+
+    // Check for null pointers
+    if (fDotEquivalents == NULL || fCommaEquivalents == NULL || fOtherGroupingSeparators == NULL ||
+               fStrictDotEquivalents == NULL || fStrictCommaEquivalents == NULL || fStrictOtherGroupingSeparators == NULL ||
+               fDefaultGroupingSeparators == NULL || fStrictOtherGroupingSeparators == NULL) {
+        goto ExitConstrDeleteAll;
+    }
+
+    // Freeze all the sets
+    fDotEquivalents->freeze();
+    fCommaEquivalents->freeze();
+    fOtherGroupingSeparators->freeze();
+    fStrictDotEquivalents->freeze();
+    fStrictCommaEquivalents->freeze();
+    fStrictOtherGroupingSeparators->freeze();
+    fDefaultGroupingSeparators->freeze();
+    fStrictDefaultGroupingSeparators->freeze();
+       
+    return; // If we reached this point, everything is fine so just exit
+
+ExitConstrDeleteAll: // Remove fPropSets and fRuleSets and return error
+    delete fDotEquivalents; fDotEquivalents = NULL;
+    delete fCommaEquivalents; fCommaEquivalents = NULL;
+    delete fOtherGroupingSeparators; fOtherGroupingSeparators = NULL;
+    delete fStrictDotEquivalents; fStrictDotEquivalents = NULL;
+    delete fStrictCommaEquivalents; fStrictCommaEquivalents = NULL;
+    delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
+    delete fDefaultGroupingSeparators; fDefaultGroupingSeparators = NULL;
+    delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
+
+    *status = U_MEMORY_ALLOCATION_ERROR;
+}
+
+
+DecimalFormatStaticSets::~DecimalFormatStaticSets() {
+    delete fDotEquivalents; fDotEquivalents = NULL;
+    delete fCommaEquivalents; fCommaEquivalents = NULL;
+    delete fOtherGroupingSeparators; fOtherGroupingSeparators = NULL;
+    delete fStrictDotEquivalents; fStrictDotEquivalents = NULL;
+    delete fStrictCommaEquivalents; fStrictCommaEquivalents = NULL;
+    delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
+    delete fDefaultGroupingSeparators; fDefaultGroupingSeparators = NULL;
+    delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
+}
+
+
+//------------------------------------------------------------------------------
+//
+//   decfmt_cleanup     Memory cleanup function, free/delete all
+//                      cached memory.  Called by ICU's u_cleanup() function.
+//
+//------------------------------------------------------------------------------
+UBool
+DecimalFormatStaticSets::cleanup(void)
+{
+    delete DecimalFormatStaticSets::gStaticSets;
+    DecimalFormatStaticSets::gStaticSets = NULL;
+
+    return TRUE;
+}
+
+U_CDECL_BEGIN
+static UBool U_CALLCONV
+decimfmt_cleanup(void)
+{
+    return DecimalFormatStaticSets::cleanup();
+}
+U_CDECL_END
+
+void DecimalFormatStaticSets::initSets(UErrorCode *status)
+{
+       DecimalFormatStaticSets *p;
+
+    UMTX_CHECK(NULL, gStaticSets, p);
+    if (p == NULL) {
+        p = new DecimalFormatStaticSets(status);
+
+        if (p == NULL) {
+               *status = U_MEMORY_ALLOCATION_ERROR;
+               return;
+        }
+
+        if (U_FAILURE(*status)) {
+            delete p;
+            return;
+        }
+
+        umtx_lock(NULL);
+        if (gStaticSets == NULL) {
+            gStaticSets = p;
+            p = NULL;
+        }
+
+        umtx_unlock(NULL);
+        if (p != NULL) {
+            delete p;
+        }
+
+        ucln_i18n_registerCleanup(UCLN_I18N_DECFMT, decimfmt_cleanup);
+    }
+}
+
+UnicodeSet *DecimalFormatStaticSets::getSimilarDecimals(UChar32 decimal, UBool strictParse, UnicodeSet *fallback)
+{
+       UErrorCode status = U_ZERO_ERROR;
+
+       initSets(&status);
+
+       if (U_FAILURE(status)) {
+               fallback->set(decimal, decimal);
+               return fallback;
+       }
+
+    if (gStaticSets->fDotEquivalents->contains(decimal)) {
+        return strictParse ? gStaticSets->fStrictDotEquivalents : gStaticSets->fDotEquivalents;
+    }
+
+    if (gStaticSets->fCommaEquivalents->contains(decimal)) {
+        return strictParse ? gStaticSets->fStrictCommaEquivalents : gStaticSets->fCommaEquivalents;
+    }
+
+    // if there is no match, return the character itself
+    fallback->set(decimal, decimal);
+    return fallback;
+}
+
+
+U_NAMESPACE_END