intl/icu/source/i18n/decfmtst.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /*
     2 *******************************************************************************
     3 * Copyright (C) 2009-2013, International Business Machines Corporation and    *
     4 * others. All Rights Reserved.                                                *
     5 *******************************************************************************
     6 *
     7 * This file contains the class DecimalFormatStaticSets
     8 *
     9 * DecimalFormatStaticSets holds the UnicodeSets that are needed for lenient
    10 * parsing of decimal and group separators.
    11 ********************************************************************************
    12 */
    14 #include "unicode/utypes.h"
    16 #if !UCONFIG_NO_FORMATTING
    18 #include "unicode/unistr.h"
    19 #include "unicode/uniset.h"
    20 #include "unicode/uchar.h"
    21 #include "cmemory.h"
    22 #include "cstring.h"
    23 #include "uassert.h"
    24 #include "ucln_in.h"
    25 #include "umutex.h"
    27 #include "decfmtst.h"
    29 U_NAMESPACE_BEGIN
    32 //------------------------------------------------------------------------------
    33 //
    34 // Unicode Set pattern strings for all of the required constant sets.
    35 //               Initialized with hex values for portability to EBCDIC based machines.
    36 //                Really ugly, but there's no good way to avoid it.
    37 //
    38 //------------------------------------------------------------------------------
    40 static const UChar gDotEquivalentsPattern[] = {
    41         // [       .    \u2024  \u3002  \uFE12  \uFE52  \uFF0E  \uFF61     ]
    42         0x005B, 0x002E, 0x2024, 0x3002, 0xFE12, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
    44 static const UChar gCommaEquivalentsPattern[] = {
    45         // [       ,    \u060C  \u066B  \u3001  \uFE10  \uFE11  \uFE50  \uFE51  \uFF0C  \uFF64    ]
    46         0x005B, 0x002C, 0x060C, 0x066B, 0x3001, 0xFE10, 0xFE11, 0xFE50, 0xFE51, 0xFF0C, 0xFF64, 0x005D, 0x0000};
    48 static const UChar gOtherGroupingSeparatorsPattern[] = {
    49         // [       \     SPACE     '      NBSP  \u066C  \u2000     -    \u200A  \u2018  \u2019  \u202F  \u205F  \u3000  \uFF07     ]
    50         0x005B, 0x005C, 0x0020, 0x0027, 0x00A0, 0x066C, 0x2000, 0x002D, 0x200A, 0x2018, 0x2019, 0x202F, 0x205F, 0x3000, 0xFF07, 0x005D, 0x0000};
    52 static const UChar gDashEquivalentsPattern[] = {
    53         // [       \      -     HYPHEN  F_DASH  N_DASH   MINUS     ]
    54         0x005B, 0x005C, 0x002D, 0x2010, 0x2012, 0x2013, 0x2212, 0x005D, 0x0000};
    56 static const UChar gStrictDotEquivalentsPattern[] = {
    57         // [      .     \u2024  \uFE52  \uFF0E  \uFF61    ]
    58         0x005B, 0x002E, 0x2024, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
    60 static const UChar gStrictCommaEquivalentsPattern[] = {
    61         // [       ,    \u066B  \uFE10  \uFE50  \uFF0C     ]
    62         0x005B, 0x002C, 0x066B, 0xFE10, 0xFE50, 0xFF0C, 0x005D, 0x0000};
    64 static const UChar gStrictOtherGroupingSeparatorsPattern[] = {
    65         // [       \     SPACE     '      NBSP  \u066C  \u2000     -    \u200A  \u2018  \u2019  \u202F  \u205F  \u3000  \uFF07     ]
    66         0x005B, 0x005C, 0x0020, 0x0027, 0x00A0, 0x066C, 0x2000, 0x002D, 0x200A, 0x2018, 0x2019, 0x202F, 0x205F, 0x3000, 0xFF07, 0x005D, 0x0000};
    68 static const UChar gStrictDashEquivalentsPattern[] = {
    69         // [       \      -      MINUS     ]
    70         0x005B, 0x005C, 0x002D, 0x2212, 0x005D, 0x0000};
    72 static UChar32 gMinusSigns[] = {
    73     0x002D,
    74     0x207B,
    75     0x208B,
    76     0x2212,
    77     0x2796,
    78     0xFE63,
    79     0xFF0D};
    81 static UChar32 gPlusSigns[] = {
    82     0x002B,
    83     0x207A,
    84     0x208A,
    85     0x2795,
    86     0xfB29,
    87     0xFE62,
    88     0xFF0B};
    90 static void initUnicodeSet(const UChar32 *raw, int32_t len, UnicodeSet *s) {
    91     for (int32_t i = 0; i < len; ++i) {
    92         s->add(raw[i]);
    93     }
    94 }
    96 DecimalFormatStaticSets::DecimalFormatStaticSets(UErrorCode &status)
    97 : fDotEquivalents(NULL),
    98   fCommaEquivalents(NULL),
    99   fOtherGroupingSeparators(NULL),
   100   fDashEquivalents(NULL),
   101   fStrictDotEquivalents(NULL),
   102   fStrictCommaEquivalents(NULL),
   103   fStrictOtherGroupingSeparators(NULL),
   104   fStrictDashEquivalents(NULL),
   105   fDefaultGroupingSeparators(NULL),
   106   fStrictDefaultGroupingSeparators(NULL),
   107   fMinusSigns(NULL),
   108   fPlusSigns(NULL)
   109 {
   110     fDotEquivalents                = new UnicodeSet(UnicodeString(TRUE, gDotEquivalentsPattern, -1),                status);
   111     fCommaEquivalents              = new UnicodeSet(UnicodeString(TRUE, gCommaEquivalentsPattern, -1),              status);
   112     fOtherGroupingSeparators       = new UnicodeSet(UnicodeString(TRUE, gOtherGroupingSeparatorsPattern, -1),       status);
   113     fDashEquivalents               = new UnicodeSet(UnicodeString(TRUE, gDashEquivalentsPattern, -1),               status);
   115     fStrictDotEquivalents          = new UnicodeSet(UnicodeString(TRUE, gStrictDotEquivalentsPattern, -1),          status);
   116     fStrictCommaEquivalents        = new UnicodeSet(UnicodeString(TRUE, gStrictCommaEquivalentsPattern, -1),        status);
   117     fStrictOtherGroupingSeparators = new UnicodeSet(UnicodeString(TRUE, gStrictOtherGroupingSeparatorsPattern, -1), status);
   118     fStrictDashEquivalents         = new UnicodeSet(UnicodeString(TRUE, gStrictDashEquivalentsPattern, -1),         status);
   121     fDefaultGroupingSeparators = new UnicodeSet(*fDotEquivalents);
   122     fDefaultGroupingSeparators->addAll(*fCommaEquivalents);
   123     fDefaultGroupingSeparators->addAll(*fOtherGroupingSeparators);
   125     fStrictDefaultGroupingSeparators = new UnicodeSet(*fStrictDotEquivalents);
   126     fStrictDefaultGroupingSeparators->addAll(*fStrictCommaEquivalents);
   127     fStrictDefaultGroupingSeparators->addAll(*fStrictOtherGroupingSeparators);
   129     fMinusSigns = new UnicodeSet();
   130     fPlusSigns = new UnicodeSet();
   132     // Check for null pointers
   133     if (fDotEquivalents == NULL || fCommaEquivalents == NULL || fOtherGroupingSeparators == NULL || fDashEquivalents == NULL ||
   134         fStrictDotEquivalents == NULL || fStrictCommaEquivalents == NULL || fStrictOtherGroupingSeparators == NULL || fStrictDashEquivalents == NULL ||
   135         fDefaultGroupingSeparators == NULL || fStrictOtherGroupingSeparators == NULL ||
   136         fMinusSigns == NULL || fPlusSigns == NULL) {
   137       cleanup();
   138       status = U_MEMORY_ALLOCATION_ERROR;
   139       return;
   140     }
   142     initUnicodeSet(
   143             gMinusSigns,
   144             sizeof(gMinusSigns) / sizeof(gMinusSigns[0]),
   145             fMinusSigns);
   146     initUnicodeSet(
   147             gPlusSigns,
   148             sizeof(gPlusSigns) / sizeof(gPlusSigns[0]),
   149             fPlusSigns);
   151     // Freeze all the sets
   152     fDotEquivalents->freeze();
   153     fCommaEquivalents->freeze();
   154     fOtherGroupingSeparators->freeze();
   155     fDashEquivalents->freeze();
   156     fStrictDotEquivalents->freeze();
   157     fStrictCommaEquivalents->freeze();
   158     fStrictOtherGroupingSeparators->freeze();
   159     fStrictDashEquivalents->freeze();
   160     fDefaultGroupingSeparators->freeze();
   161     fStrictDefaultGroupingSeparators->freeze();
   162     fMinusSigns->freeze();
   163     fPlusSigns->freeze();
   164 }
   166 DecimalFormatStaticSets::~DecimalFormatStaticSets() {
   167   cleanup();
   168 }
   170 void DecimalFormatStaticSets::cleanup() { // Be sure to clean up newly added fields!
   171     delete fDotEquivalents; fDotEquivalents = NULL;
   172     delete fCommaEquivalents; fCommaEquivalents = NULL;
   173     delete fOtherGroupingSeparators; fOtherGroupingSeparators = NULL;
   174     delete fDashEquivalents; fDashEquivalents = NULL;
   175     delete fStrictDotEquivalents; fStrictDotEquivalents = NULL;
   176     delete fStrictCommaEquivalents; fStrictCommaEquivalents = NULL;
   177     delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
   178     delete fStrictDashEquivalents; fStrictDashEquivalents = NULL;
   179     delete fDefaultGroupingSeparators; fDefaultGroupingSeparators = NULL;
   180     delete fStrictDefaultGroupingSeparators; fStrictDefaultGroupingSeparators = NULL;
   181     delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
   182     delete fMinusSigns; fMinusSigns = NULL;
   183     delete fPlusSigns; fPlusSigns = NULL;
   184 }
   186 static DecimalFormatStaticSets *gStaticSets;
   187 static icu::UInitOnce gStaticSetsInitOnce = U_INITONCE_INITIALIZER;
   190 //------------------------------------------------------------------------------
   191 //
   192 //   decfmt_cleanup     Memory cleanup function, free/delete all
   193 //                      cached memory.  Called by ICU's u_cleanup() function.
   194 //
   195 //------------------------------------------------------------------------------
   196 U_CDECL_BEGIN
   197 static UBool U_CALLCONV
   198 decimfmt_cleanup(void)
   199 {
   200     delete gStaticSets;
   201     gStaticSets = NULL;
   202     gStaticSetsInitOnce.reset();
   203     return TRUE;
   204 }
   206 static void U_CALLCONV initSets(UErrorCode &status) {
   207     U_ASSERT(gStaticSets == NULL);
   208     ucln_i18n_registerCleanup(UCLN_I18N_DECFMT, decimfmt_cleanup);
   209     gStaticSets = new DecimalFormatStaticSets(status);
   210     if (U_FAILURE(status)) {
   211         delete gStaticSets;
   212         gStaticSets = NULL;
   213         return;
   214     }
   215     if (gStaticSets == NULL) {
   216         status = U_MEMORY_ALLOCATION_ERROR;
   217     }
   218 }
   219 U_CDECL_END
   221 const DecimalFormatStaticSets *DecimalFormatStaticSets::getStaticSets(UErrorCode &status) {
   222     umtx_initOnce(gStaticSetsInitOnce, initSets, status);
   223     return gStaticSets;
   224 }
   227 const UnicodeSet *DecimalFormatStaticSets::getSimilarDecimals(UChar32 decimal, UBool strictParse)
   228 {
   229     UErrorCode status = U_ZERO_ERROR;
   230     umtx_initOnce(gStaticSetsInitOnce, initSets, status);
   231     if (U_FAILURE(status)) {
   232         return NULL;
   233     }
   235     if (gStaticSets->fDotEquivalents->contains(decimal)) {
   236         return strictParse ? gStaticSets->fStrictDotEquivalents : gStaticSets->fDotEquivalents;
   237     }
   239     if (gStaticSets->fCommaEquivalents->contains(decimal)) {
   240         return strictParse ? gStaticSets->fStrictCommaEquivalents : gStaticSets->fCommaEquivalents;
   241     }
   243     // if there is no match, return NULL
   244     return NULL;
   245 }
   248 U_NAMESPACE_END
   249 #endif   // !UCONFIG_NO_FORMATTING

mercurial