intl/icu/source/i18n/decfmtst.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/intl/icu/source/i18n/decfmtst.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,249 @@
     1.4 +/*
     1.5 +*******************************************************************************
     1.6 +* Copyright (C) 2009-2013, International Business Machines Corporation and    *
     1.7 +* others. All Rights Reserved.                                                *
     1.8 +*******************************************************************************
     1.9 +*
    1.10 +* This file contains the class DecimalFormatStaticSets
    1.11 +*
    1.12 +* DecimalFormatStaticSets holds the UnicodeSets that are needed for lenient
    1.13 +* parsing of decimal and group separators.
    1.14 +********************************************************************************
    1.15 +*/
    1.16 +
    1.17 +#include "unicode/utypes.h"
    1.18 +
    1.19 +#if !UCONFIG_NO_FORMATTING
    1.20 +
    1.21 +#include "unicode/unistr.h"
    1.22 +#include "unicode/uniset.h"
    1.23 +#include "unicode/uchar.h"
    1.24 +#include "cmemory.h"
    1.25 +#include "cstring.h"
    1.26 +#include "uassert.h"
    1.27 +#include "ucln_in.h"
    1.28 +#include "umutex.h"
    1.29 +
    1.30 +#include "decfmtst.h"
    1.31 +
    1.32 +U_NAMESPACE_BEGIN
    1.33 +
    1.34 +
    1.35 +//------------------------------------------------------------------------------
    1.36 +//
    1.37 +// Unicode Set pattern strings for all of the required constant sets.
    1.38 +//               Initialized with hex values for portability to EBCDIC based machines.
    1.39 +//                Really ugly, but there's no good way to avoid it.
    1.40 +//
    1.41 +//------------------------------------------------------------------------------
    1.42 +
    1.43 +static const UChar gDotEquivalentsPattern[] = {
    1.44 +        // [       .    \u2024  \u3002  \uFE12  \uFE52  \uFF0E  \uFF61     ]
    1.45 +        0x005B, 0x002E, 0x2024, 0x3002, 0xFE12, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
    1.46 +
    1.47 +static const UChar gCommaEquivalentsPattern[] = {
    1.48 +        // [       ,    \u060C  \u066B  \u3001  \uFE10  \uFE11  \uFE50  \uFE51  \uFF0C  \uFF64    ]
    1.49 +        0x005B, 0x002C, 0x060C, 0x066B, 0x3001, 0xFE10, 0xFE11, 0xFE50, 0xFE51, 0xFF0C, 0xFF64, 0x005D, 0x0000};
    1.50 +
    1.51 +static const UChar gOtherGroupingSeparatorsPattern[] = {
    1.52 +        // [       \     SPACE     '      NBSP  \u066C  \u2000     -    \u200A  \u2018  \u2019  \u202F  \u205F  \u3000  \uFF07     ]
    1.53 +        0x005B, 0x005C, 0x0020, 0x0027, 0x00A0, 0x066C, 0x2000, 0x002D, 0x200A, 0x2018, 0x2019, 0x202F, 0x205F, 0x3000, 0xFF07, 0x005D, 0x0000};
    1.54 +
    1.55 +static const UChar gDashEquivalentsPattern[] = {
    1.56 +        // [       \      -     HYPHEN  F_DASH  N_DASH   MINUS     ]
    1.57 +        0x005B, 0x005C, 0x002D, 0x2010, 0x2012, 0x2013, 0x2212, 0x005D, 0x0000};
    1.58 +
    1.59 +static const UChar gStrictDotEquivalentsPattern[] = {
    1.60 +        // [      .     \u2024  \uFE52  \uFF0E  \uFF61    ]
    1.61 +        0x005B, 0x002E, 0x2024, 0xFE52, 0xFF0E, 0xFF61, 0x005D, 0x0000};
    1.62 +
    1.63 +static const UChar gStrictCommaEquivalentsPattern[] = {
    1.64 +        // [       ,    \u066B  \uFE10  \uFE50  \uFF0C     ]
    1.65 +        0x005B, 0x002C, 0x066B, 0xFE10, 0xFE50, 0xFF0C, 0x005D, 0x0000};
    1.66 +
    1.67 +static const UChar gStrictOtherGroupingSeparatorsPattern[] = {
    1.68 +        // [       \     SPACE     '      NBSP  \u066C  \u2000     -    \u200A  \u2018  \u2019  \u202F  \u205F  \u3000  \uFF07     ]
    1.69 +        0x005B, 0x005C, 0x0020, 0x0027, 0x00A0, 0x066C, 0x2000, 0x002D, 0x200A, 0x2018, 0x2019, 0x202F, 0x205F, 0x3000, 0xFF07, 0x005D, 0x0000};
    1.70 +
    1.71 +static const UChar gStrictDashEquivalentsPattern[] = {
    1.72 +        // [       \      -      MINUS     ]
    1.73 +        0x005B, 0x005C, 0x002D, 0x2212, 0x005D, 0x0000};
    1.74 +
    1.75 +static UChar32 gMinusSigns[] = {
    1.76 +    0x002D,
    1.77 +    0x207B,
    1.78 +    0x208B,
    1.79 +    0x2212,
    1.80 +    0x2796,
    1.81 +    0xFE63,
    1.82 +    0xFF0D};
    1.83 +
    1.84 +static UChar32 gPlusSigns[] = {
    1.85 +    0x002B,
    1.86 +    0x207A,
    1.87 +    0x208A,
    1.88 +    0x2795,
    1.89 +    0xfB29,
    1.90 +    0xFE62,
    1.91 +    0xFF0B};
    1.92 +
    1.93 +static void initUnicodeSet(const UChar32 *raw, int32_t len, UnicodeSet *s) {
    1.94 +    for (int32_t i = 0; i < len; ++i) {
    1.95 +        s->add(raw[i]);
    1.96 +    }
    1.97 +}
    1.98 +
    1.99 +DecimalFormatStaticSets::DecimalFormatStaticSets(UErrorCode &status)
   1.100 +: fDotEquivalents(NULL),
   1.101 +  fCommaEquivalents(NULL),
   1.102 +  fOtherGroupingSeparators(NULL),
   1.103 +  fDashEquivalents(NULL),
   1.104 +  fStrictDotEquivalents(NULL),
   1.105 +  fStrictCommaEquivalents(NULL),
   1.106 +  fStrictOtherGroupingSeparators(NULL),
   1.107 +  fStrictDashEquivalents(NULL),
   1.108 +  fDefaultGroupingSeparators(NULL),
   1.109 +  fStrictDefaultGroupingSeparators(NULL),
   1.110 +  fMinusSigns(NULL),
   1.111 +  fPlusSigns(NULL)
   1.112 +{
   1.113 +    fDotEquivalents                = new UnicodeSet(UnicodeString(TRUE, gDotEquivalentsPattern, -1),                status);
   1.114 +    fCommaEquivalents              = new UnicodeSet(UnicodeString(TRUE, gCommaEquivalentsPattern, -1),              status);
   1.115 +    fOtherGroupingSeparators       = new UnicodeSet(UnicodeString(TRUE, gOtherGroupingSeparatorsPattern, -1),       status);
   1.116 +    fDashEquivalents               = new UnicodeSet(UnicodeString(TRUE, gDashEquivalentsPattern, -1),               status);
   1.117 +    
   1.118 +    fStrictDotEquivalents          = new UnicodeSet(UnicodeString(TRUE, gStrictDotEquivalentsPattern, -1),          status);
   1.119 +    fStrictCommaEquivalents        = new UnicodeSet(UnicodeString(TRUE, gStrictCommaEquivalentsPattern, -1),        status);
   1.120 +    fStrictOtherGroupingSeparators = new UnicodeSet(UnicodeString(TRUE, gStrictOtherGroupingSeparatorsPattern, -1), status);
   1.121 +    fStrictDashEquivalents         = new UnicodeSet(UnicodeString(TRUE, gStrictDashEquivalentsPattern, -1),         status);
   1.122 +
   1.123 +
   1.124 +    fDefaultGroupingSeparators = new UnicodeSet(*fDotEquivalents);
   1.125 +    fDefaultGroupingSeparators->addAll(*fCommaEquivalents);
   1.126 +    fDefaultGroupingSeparators->addAll(*fOtherGroupingSeparators);
   1.127 +
   1.128 +    fStrictDefaultGroupingSeparators = new UnicodeSet(*fStrictDotEquivalents);
   1.129 +    fStrictDefaultGroupingSeparators->addAll(*fStrictCommaEquivalents);
   1.130 +    fStrictDefaultGroupingSeparators->addAll(*fStrictOtherGroupingSeparators);
   1.131 +
   1.132 +    fMinusSigns = new UnicodeSet();
   1.133 +    fPlusSigns = new UnicodeSet();
   1.134 +
   1.135 +    // Check for null pointers
   1.136 +    if (fDotEquivalents == NULL || fCommaEquivalents == NULL || fOtherGroupingSeparators == NULL || fDashEquivalents == NULL ||
   1.137 +        fStrictDotEquivalents == NULL || fStrictCommaEquivalents == NULL || fStrictOtherGroupingSeparators == NULL || fStrictDashEquivalents == NULL ||
   1.138 +        fDefaultGroupingSeparators == NULL || fStrictOtherGroupingSeparators == NULL ||
   1.139 +        fMinusSigns == NULL || fPlusSigns == NULL) {
   1.140 +      cleanup();
   1.141 +      status = U_MEMORY_ALLOCATION_ERROR;
   1.142 +      return;
   1.143 +    }
   1.144 +
   1.145 +    initUnicodeSet(
   1.146 +            gMinusSigns,
   1.147 +            sizeof(gMinusSigns) / sizeof(gMinusSigns[0]),
   1.148 +            fMinusSigns);
   1.149 +    initUnicodeSet(
   1.150 +            gPlusSigns,
   1.151 +            sizeof(gPlusSigns) / sizeof(gPlusSigns[0]),
   1.152 +            fPlusSigns);
   1.153 +
   1.154 +    // Freeze all the sets
   1.155 +    fDotEquivalents->freeze();
   1.156 +    fCommaEquivalents->freeze();
   1.157 +    fOtherGroupingSeparators->freeze();
   1.158 +    fDashEquivalents->freeze();
   1.159 +    fStrictDotEquivalents->freeze();
   1.160 +    fStrictCommaEquivalents->freeze();
   1.161 +    fStrictOtherGroupingSeparators->freeze();
   1.162 +    fStrictDashEquivalents->freeze();
   1.163 +    fDefaultGroupingSeparators->freeze();
   1.164 +    fStrictDefaultGroupingSeparators->freeze();
   1.165 +    fMinusSigns->freeze();
   1.166 +    fPlusSigns->freeze();
   1.167 +}
   1.168 +
   1.169 +DecimalFormatStaticSets::~DecimalFormatStaticSets() {
   1.170 +  cleanup();
   1.171 +}
   1.172 +
   1.173 +void DecimalFormatStaticSets::cleanup() { // Be sure to clean up newly added fields!
   1.174 +    delete fDotEquivalents; fDotEquivalents = NULL;
   1.175 +    delete fCommaEquivalents; fCommaEquivalents = NULL;
   1.176 +    delete fOtherGroupingSeparators; fOtherGroupingSeparators = NULL;
   1.177 +    delete fDashEquivalents; fDashEquivalents = NULL;
   1.178 +    delete fStrictDotEquivalents; fStrictDotEquivalents = NULL;
   1.179 +    delete fStrictCommaEquivalents; fStrictCommaEquivalents = NULL;
   1.180 +    delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
   1.181 +    delete fStrictDashEquivalents; fStrictDashEquivalents = NULL;
   1.182 +    delete fDefaultGroupingSeparators; fDefaultGroupingSeparators = NULL;
   1.183 +    delete fStrictDefaultGroupingSeparators; fStrictDefaultGroupingSeparators = NULL;
   1.184 +    delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
   1.185 +    delete fMinusSigns; fMinusSigns = NULL;
   1.186 +    delete fPlusSigns; fPlusSigns = NULL;
   1.187 +}
   1.188 +
   1.189 +static DecimalFormatStaticSets *gStaticSets;
   1.190 +static icu::UInitOnce gStaticSetsInitOnce = U_INITONCE_INITIALIZER;
   1.191 +
   1.192 +
   1.193 +//------------------------------------------------------------------------------
   1.194 +//
   1.195 +//   decfmt_cleanup     Memory cleanup function, free/delete all
   1.196 +//                      cached memory.  Called by ICU's u_cleanup() function.
   1.197 +//
   1.198 +//------------------------------------------------------------------------------
   1.199 +U_CDECL_BEGIN
   1.200 +static UBool U_CALLCONV
   1.201 +decimfmt_cleanup(void)
   1.202 +{
   1.203 +    delete gStaticSets;
   1.204 +    gStaticSets = NULL;
   1.205 +    gStaticSetsInitOnce.reset();
   1.206 +    return TRUE;
   1.207 +}
   1.208 +
   1.209 +static void U_CALLCONV initSets(UErrorCode &status) {
   1.210 +    U_ASSERT(gStaticSets == NULL);
   1.211 +    ucln_i18n_registerCleanup(UCLN_I18N_DECFMT, decimfmt_cleanup);
   1.212 +    gStaticSets = new DecimalFormatStaticSets(status);
   1.213 +    if (U_FAILURE(status)) {
   1.214 +        delete gStaticSets;
   1.215 +        gStaticSets = NULL;
   1.216 +        return;
   1.217 +    }
   1.218 +    if (gStaticSets == NULL) {
   1.219 +        status = U_MEMORY_ALLOCATION_ERROR;
   1.220 +    }
   1.221 +}
   1.222 +U_CDECL_END
   1.223 +
   1.224 +const DecimalFormatStaticSets *DecimalFormatStaticSets::getStaticSets(UErrorCode &status) {
   1.225 +    umtx_initOnce(gStaticSetsInitOnce, initSets, status);
   1.226 +    return gStaticSets;
   1.227 +}
   1.228 +
   1.229 +
   1.230 +const UnicodeSet *DecimalFormatStaticSets::getSimilarDecimals(UChar32 decimal, UBool strictParse)
   1.231 +{
   1.232 +    UErrorCode status = U_ZERO_ERROR;
   1.233 +    umtx_initOnce(gStaticSetsInitOnce, initSets, status);
   1.234 +    if (U_FAILURE(status)) {
   1.235 +        return NULL;
   1.236 +    }
   1.237 +
   1.238 +    if (gStaticSets->fDotEquivalents->contains(decimal)) {
   1.239 +        return strictParse ? gStaticSets->fStrictDotEquivalents : gStaticSets->fDotEquivalents;
   1.240 +    }
   1.241 +
   1.242 +    if (gStaticSets->fCommaEquivalents->contains(decimal)) {
   1.243 +        return strictParse ? gStaticSets->fStrictCommaEquivalents : gStaticSets->fCommaEquivalents;
   1.244 +    }
   1.245 +
   1.246 +    // if there is no match, return NULL
   1.247 +    return NULL;
   1.248 +}
   1.249 +
   1.250 +
   1.251 +U_NAMESPACE_END
   1.252 +#endif   // !UCONFIG_NO_FORMATTING

mercurial