a82e70e5b1
X-SVN-Rev: 40065
252 lines
9.4 KiB
C++
252 lines
9.4 KiB
C++
// © 2016 and later: Unicode, Inc. and others.
|
|
// License & terms of use: http://www.unicode.org/copyright.html
|
|
/*
|
|
*******************************************************************************
|
|
* Copyright (C) 2009-2016, 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"
|
|
|
|
#if !UCONFIG_NO_FORMATTING
|
|
|
|
#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 gDashEquivalentsPattern[] = {
|
|
// [ \ - HYPHEN F_DASH N_DASH MINUS ]
|
|
0x005B, 0x005C, 0x002D, 0x2010, 0x2012, 0x2013, 0x2212, 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};
|
|
|
|
static const UChar gStrictDashEquivalentsPattern[] = {
|
|
// [ \ - MINUS ]
|
|
0x005B, 0x005C, 0x002D, 0x2212, 0x005D, 0x0000};
|
|
|
|
static const UChar32 gMinusSigns[] = {
|
|
0x002D,
|
|
0x207B,
|
|
0x208B,
|
|
0x2212,
|
|
0x2796,
|
|
0xFE63,
|
|
0xFF0D};
|
|
|
|
static const UChar32 gPlusSigns[] = {
|
|
0x002B,
|
|
0x207A,
|
|
0x208A,
|
|
0x2795,
|
|
0xfB29,
|
|
0xFE62,
|
|
0xFF0B};
|
|
|
|
static void initUnicodeSet(const UChar32 *raw, int32_t len, UnicodeSet *s) {
|
|
for (int32_t i = 0; i < len; ++i) {
|
|
s->add(raw[i]);
|
|
}
|
|
}
|
|
|
|
DecimalFormatStaticSets::DecimalFormatStaticSets(UErrorCode &status)
|
|
: fDotEquivalents(NULL),
|
|
fCommaEquivalents(NULL),
|
|
fOtherGroupingSeparators(NULL),
|
|
fDashEquivalents(NULL),
|
|
fStrictDotEquivalents(NULL),
|
|
fStrictCommaEquivalents(NULL),
|
|
fStrictOtherGroupingSeparators(NULL),
|
|
fStrictDashEquivalents(NULL),
|
|
fDefaultGroupingSeparators(NULL),
|
|
fStrictDefaultGroupingSeparators(NULL),
|
|
fMinusSigns(NULL),
|
|
fPlusSigns(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);
|
|
fDashEquivalents = new UnicodeSet(UnicodeString(TRUE, gDashEquivalentsPattern, -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);
|
|
fStrictDashEquivalents = new UnicodeSet(UnicodeString(TRUE, gStrictDashEquivalentsPattern, -1), status);
|
|
|
|
|
|
fDefaultGroupingSeparators = new UnicodeSet(*fDotEquivalents);
|
|
fDefaultGroupingSeparators->addAll(*fCommaEquivalents);
|
|
fDefaultGroupingSeparators->addAll(*fOtherGroupingSeparators);
|
|
|
|
fStrictDefaultGroupingSeparators = new UnicodeSet(*fStrictDotEquivalents);
|
|
fStrictDefaultGroupingSeparators->addAll(*fStrictCommaEquivalents);
|
|
fStrictDefaultGroupingSeparators->addAll(*fStrictOtherGroupingSeparators);
|
|
|
|
fMinusSigns = new UnicodeSet();
|
|
fPlusSigns = new UnicodeSet();
|
|
|
|
// Check for null pointers
|
|
if (fDotEquivalents == NULL || fCommaEquivalents == NULL || fOtherGroupingSeparators == NULL || fDashEquivalents == NULL ||
|
|
fStrictDotEquivalents == NULL || fStrictCommaEquivalents == NULL || fStrictOtherGroupingSeparators == NULL || fStrictDashEquivalents == NULL ||
|
|
fDefaultGroupingSeparators == NULL || fStrictOtherGroupingSeparators == NULL ||
|
|
fMinusSigns == NULL || fPlusSigns == NULL) {
|
|
cleanup();
|
|
status = U_MEMORY_ALLOCATION_ERROR;
|
|
return;
|
|
}
|
|
|
|
initUnicodeSet(
|
|
gMinusSigns,
|
|
UPRV_LENGTHOF(gMinusSigns),
|
|
fMinusSigns);
|
|
initUnicodeSet(
|
|
gPlusSigns,
|
|
UPRV_LENGTHOF(gPlusSigns),
|
|
fPlusSigns);
|
|
|
|
// Freeze all the sets
|
|
fDotEquivalents->freeze();
|
|
fCommaEquivalents->freeze();
|
|
fOtherGroupingSeparators->freeze();
|
|
fDashEquivalents->freeze();
|
|
fStrictDotEquivalents->freeze();
|
|
fStrictCommaEquivalents->freeze();
|
|
fStrictOtherGroupingSeparators->freeze();
|
|
fStrictDashEquivalents->freeze();
|
|
fDefaultGroupingSeparators->freeze();
|
|
fStrictDefaultGroupingSeparators->freeze();
|
|
fMinusSigns->freeze();
|
|
fPlusSigns->freeze();
|
|
}
|
|
|
|
DecimalFormatStaticSets::~DecimalFormatStaticSets() {
|
|
cleanup();
|
|
}
|
|
|
|
void DecimalFormatStaticSets::cleanup() { // Be sure to clean up newly added fields!
|
|
delete fDotEquivalents; fDotEquivalents = NULL;
|
|
delete fCommaEquivalents; fCommaEquivalents = NULL;
|
|
delete fOtherGroupingSeparators; fOtherGroupingSeparators = NULL;
|
|
delete fDashEquivalents; fDashEquivalents = NULL;
|
|
delete fStrictDotEquivalents; fStrictDotEquivalents = NULL;
|
|
delete fStrictCommaEquivalents; fStrictCommaEquivalents = NULL;
|
|
delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
|
|
delete fStrictDashEquivalents; fStrictDashEquivalents = NULL;
|
|
delete fDefaultGroupingSeparators; fDefaultGroupingSeparators = NULL;
|
|
delete fStrictDefaultGroupingSeparators; fStrictDefaultGroupingSeparators = NULL;
|
|
delete fStrictOtherGroupingSeparators; fStrictOtherGroupingSeparators = NULL;
|
|
delete fMinusSigns; fMinusSigns = NULL;
|
|
delete fPlusSigns; fPlusSigns = NULL;
|
|
}
|
|
|
|
static DecimalFormatStaticSets *gStaticSets;
|
|
static icu::UInitOnce gStaticSetsInitOnce = U_INITONCE_INITIALIZER;
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
// decfmt_cleanup Memory cleanup function, free/delete all
|
|
// cached memory. Called by ICU's u_cleanup() function.
|
|
//
|
|
//------------------------------------------------------------------------------
|
|
U_CDECL_BEGIN
|
|
static UBool U_CALLCONV
|
|
decimfmt_cleanup(void)
|
|
{
|
|
delete gStaticSets;
|
|
gStaticSets = NULL;
|
|
gStaticSetsInitOnce.reset();
|
|
return TRUE;
|
|
}
|
|
|
|
static void U_CALLCONV initSets(UErrorCode &status) {
|
|
U_ASSERT(gStaticSets == NULL);
|
|
ucln_i18n_registerCleanup(UCLN_I18N_DECFMT, decimfmt_cleanup);
|
|
gStaticSets = new DecimalFormatStaticSets(status);
|
|
if (U_FAILURE(status)) {
|
|
delete gStaticSets;
|
|
gStaticSets = NULL;
|
|
return;
|
|
}
|
|
if (gStaticSets == NULL) {
|
|
status = U_MEMORY_ALLOCATION_ERROR;
|
|
}
|
|
}
|
|
U_CDECL_END
|
|
|
|
const DecimalFormatStaticSets *DecimalFormatStaticSets::getStaticSets(UErrorCode &status) {
|
|
umtx_initOnce(gStaticSetsInitOnce, initSets, status);
|
|
return gStaticSets;
|
|
}
|
|
|
|
|
|
const UnicodeSet *DecimalFormatStaticSets::getSimilarDecimals(UChar32 decimal, UBool strictParse)
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
umtx_initOnce(gStaticSetsInitOnce, initSets, status);
|
|
if (U_FAILURE(status)) {
|
|
return NULL;
|
|
}
|
|
|
|
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 NULL
|
|
return NULL;
|
|
}
|
|
|
|
|
|
U_NAMESPACE_END
|
|
#endif // !UCONFIG_NO_FORMATTING
|