From 30feb0c56bd35fb0de9f7a41bec0a56e8c2b3e5c Mon Sep 17 00:00:00 2001 From: Peter Edberg Date: Thu, 12 Sep 2013 04:33:03 +0000 Subject: [PATCH] ICU-10039 Per API review: Add consts, add unumsys_getDescription(), improve documentation X-SVN-Rev: 34283 --- icu4c/source/i18n/numsys.cpp | 8 +-- icu4c/source/i18n/unicode/numsys.h | 31 +++++--- icu4c/source/i18n/unicode/unumsys.h | 101 ++++++++++++++++++--------- icu4c/source/i18n/unumsys.cpp | 24 ++++++- icu4c/source/test/cintltst/cnumtst.c | 40 ++++++++--- 5 files changed, 145 insertions(+), 59 deletions(-) diff --git a/icu4c/source/i18n/numsys.cpp b/icu4c/source/i18n/numsys.cpp index 6ea76f7517b..288cc56309c 100644 --- a/icu4c/source/i18n/numsys.cpp +++ b/icu4c/source/i18n/numsys.cpp @@ -1,6 +1,6 @@ /* ******************************************************************************* -* Copyright (C) 2010-2012, International Business Machines Corporation and +* Copyright (C) 2010-2013, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************************* * @@ -208,15 +208,15 @@ NumberingSystem::createInstanceByName(const char *name, UErrorCode& status) { NumberingSystem::~NumberingSystem() { } -int32_t NumberingSystem::getRadix() { +int32_t NumberingSystem::getRadix() const { return radix; } -UnicodeString NumberingSystem::getDescription() { +UnicodeString NumberingSystem::getDescription() const { return desc; } -const char * NumberingSystem::getName() { +const char * NumberingSystem::getName() const { return name; } diff --git a/icu4c/source/i18n/unicode/numsys.h b/icu4c/source/i18n/unicode/numsys.h index e986eac2c57..2335228214c 100644 --- a/icu4c/source/i18n/unicode/numsys.h +++ b/icu4c/source/i18n/unicode/numsys.h @@ -45,7 +45,8 @@ U_NAMESPACE_BEGIN * Defines numbering systems. A numbering system describes the scheme by which * numbers are to be presented to the end user. In its simplest form, a numbering * system describes the set of digit characters that are to be used to display - * numbers, such as Western digits, Thai digits, Arabic-Indic digits, etc. + * numbers, such as Western digits, Thai digits, Arabic-Indic digits, etc., in a + * positional numbering system with a specified radix (typically 10). * More complicated numbering systems are algorithmic in nature, and require use * of an RBNF formatter ( rule based number formatter ), in order to calculate * the characters to be displayed for a given number. Examples of algorithmic @@ -111,7 +112,13 @@ public: static StringEnumeration * U_EXPORT2 getAvailableNames(UErrorCode& status); /** - * Create a numbering system from one of the predefined numbering systems known to ICU. + * Create a numbering system from one of the predefined numbering systems specified + * by CLDR and known to ICU, such as "latn", "arabext", or "hanidec"; the full list + * is returned by unumsys_openAvailableNames. Note that some of the names listed at + * http://unicode.org/repos/cldr/tags/latest/common/bcp47/number.xml - e.g. + * default, native, traditional, finance - do not identify specific numbering systems, + * but rather key values that may only be used as part of a locale, which in turn + * defines how they are mapped to a specific numbering system such as "latn" or "hant". * @param name The name of the numbering system. * @param status ICU status * @stable ICU 4.2 @@ -120,25 +127,31 @@ public: /** - * Returns the radix of this numbering system. + * Returns the radix of this numbering system. Simple positional numbering systems + * typically have radix 10, but might have a radix of e.g. 16 for hexadecimal. The + * radix is less well-defined for non-positional algorithmic systems. * @stable ICU 4.2 */ - int32_t getRadix(); + int32_t getRadix() const; /** * Returns the name of this numbering system if it was created using one of the predefined names * known to ICU. Otherwise, returns NULL. * @stable ICU 4.6 */ - const char * getName(); + const char * getName() const; /** - * Returns the description string of this numbering system, which is either - * the string of digits in the case of simple systems, or the ruleset name - * in the case of algorithmic systems. + * Returns the description string of this numbering system. For simple + * positional systems this is the ordered string of digits (with length matching + * the radix), e.g. "\u3007\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D" + * for "hanidec"; it would be "0123456789ABCDEF" for hexadecimal. For + * algorithmic systems this is the name of the RBNF ruleset used for formatting, + * e.g. "zh/SpelloutRules/%spellout-cardinal" for "hans" or "%greek-upper" for + * "grek". * @stable ICU 4.2 */ - virtual UnicodeString getDescription(); + virtual UnicodeString getDescription() const; diff --git a/icu4c/source/i18n/unicode/unumsys.h b/icu4c/source/i18n/unicode/unumsys.h index bf26b226aeb..026463e81a5 100644 --- a/icu4c/source/i18n/unicode/unumsys.h +++ b/icu4c/source/i18n/unicode/unumsys.h @@ -22,7 +22,8 @@ * Defines numbering systems. A numbering system describes the scheme by which * numbers are to be presented to the end user. In its simplest form, a numbering * system describes the set of digit characters that are to be used to display - * numbers, such as Western digits, Thai digits, Arabic-Indic digits, etc. + * numbers, such as Western digits, Thai digits, Arabic-Indic digits, etc., in a + * positional numbering system with a specified radix (typically 10). * More complicated numbering systems are algorithmic in nature, and require use * of an RBNF formatter (rule based number formatter), in order to calculate * the characters to be displayed for a given number. Examples of algorithmic @@ -43,28 +44,35 @@ struct UNumberingSystem; typedef struct UNumberingSystem UNumberingSystem; /**< C typedef for struct UNumberingSystem. @draft ICU 52 */ /** - * Opens a UNumberingSystem object using the default numbering system for the specified locale. - * @param locale The locale for which the default numbering system should be opened. - * @param status A pointer to a UErrorCode to receive any errors. For example, this may be U_UNSUPPORTED_ERROR - * for a locale such as "en@numbers=xyz" that specifies a numbering system unknown to ICU. - * @return A UNumberingSystem for the specified locale, or NULL if an error occurred. + * Opens a UNumberingSystem object using the default numbering system for the specified + * locale. + * @param locale The locale for which the default numbering system should be opened. + * @param status A pointer to a UErrorCode to receive any errors. For example, this + * may be U_UNSUPPORTED_ERROR for a locale such as "en@numbers=xyz" that + * specifies a numbering system unknown to ICU. + * @return A UNumberingSystem for the specified locale, or NULL if an error + * occurred. * @draft ICU 52 */ U_DRAFT UNumberingSystem * U_EXPORT2 unumsys_open(const char *locale, UErrorCode *status); /** - * Opens a UNumberingSystem object using the name of one of the predefined numbering systems defined by CLDR - * and known to ICU, such as "latn", "arabext", or "hanidec"; the full list is returned by unumsys_openAvailableNames. - * Note that some of the numbering systems names listed at - * http://unicode.org/repos/cldr/tags/latest/common/bcp47/number.xml - * do not identify specific numbering systems, but rather types that may only be used as part of a locale which + * Opens a UNumberingSystem object using the name of one of the predefined numbering + * systems specified by CLDR and known to ICU, such as "latn", "arabext", or "hanidec"; + * the full list is returned by unumsys_openAvailableNames. Note that some of the names + * listed at http://unicode.org/repos/cldr/tags/latest/common/bcp47/number.xml - e.g. + * default, native, traditional, finance - do not identify specific numbering systems, + * but rather key values that may only be used as part of a locale, which in turn * defines how they are mapped to a specific numbering system such as "latn" or "hant". * - * @param name The name of the numbering system for which a UNumberingSystem object should be opened. - * @param status A pointer to a UErrorCode to receive any errors. For example, this may be U_UNSUPPORTED_ERROR - * for a numbering system such as "xyz" that is unknown to ICU. - * @return A UNumberingSystem for the specified name, or NULL if an error occurred. + * @param name The name of the numbering system for which a UNumberingSystem object + * should be opened. + * @param status A pointer to a UErrorCode to receive any errors. For example, this + * may be U_UNSUPPORTED_ERROR for a numbering system such as "xyz" that + * is unknown to ICU. + * @return A UNumberingSystem for the specified name, or NULL if an error + * occurred. * @draft ICU 52 */ U_DRAFT UNumberingSystem * U_EXPORT2 @@ -72,7 +80,7 @@ unumsys_openByName(const char *name, UErrorCode *status); /** * Close a UNumberingSystem object. Once closed it may no longer be used. - * @param unumsys The UNumberingSystem object to close. + * @param unumsys The UNumberingSystem object to close. * @draft ICU 52 */ U_DRAFT void U_EXPORT2 @@ -95,40 +103,69 @@ U_NAMESPACE_END #endif /** - * Returns an enumeration over the names of all of the predefined numbering systems known to ICU. - * @param status A pointer to a UErrorCode to receive any errors. - * @return A pointer to a UEnumeration that must be closed with uenum_close(), or NULL if an error occurred. + * Returns an enumeration over the names of all of the predefined numbering systems known + * to ICU. + * @param status A pointer to a UErrorCode to receive any errors. + * @return A pointer to a UEnumeration that must be closed with uenum_close(), + * or NULL if an error occurred. * @draft ICU 52 */ U_DRAFT UEnumeration * U_EXPORT2 unumsys_openAvailableNames(UErrorCode *status); /** - * Returns the name of the specified UNumberingSystem object (if it is one of the predefined names known to ICU). - * @param unumsys The UNumberingSystem whose name is desired. - * @return A pointer to the name of the specified UNumberingSystem object, or NULL if the name is not one of the ICU predefined names. + * Returns the name of the specified UNumberingSystem object (if it is one of the + * predefined names known to ICU). + * @param unumsys The UNumberingSystem whose name is desired. + * @return A pointer to the name of the specified UNumberingSystem object, or + * NULL if the name is not one of the ICU predefined names. The pointer + * is only valid for the lifetime of the UNumberingSystem object. * @draft ICU 52 */ U_DRAFT const char * U_EXPORT2 -unumsys_getName(UNumberingSystem *unumsys); +unumsys_getName(const UNumberingSystem *unumsys); /** - * Returns the radix of the specified UNumberingSystem object. - * @param unumsys The UNumberingSystem whose radix is desired. - * @return The radix of the specified UNumberingSystem object. + * Returns whether the given UNumberingSystem object is for an algorithmic (not purely + * positional) system. + * @param unumsys The UNumberingSystem whose algorithmic status is desired. + * @return TRUE if the specified UNumberingSystem object is for an algorithmic + * system. + * @draft ICU 52 + */ +U_DRAFT UBool U_EXPORT2 +unumsys_isAlgorithmic(const UNumberingSystem *unumsys); + +/** + * Returns the radix of the specified UNumberingSystem object. Simple positional + * numbering systems typically have radix 10, but might have a radix of e.g. 16 for + * hexadecimal. The radix is less well-defined for non-positional algorithmic systems. + * @param unumsys The UNumberingSystem whose radix is desired. + * @return The radix of the specified UNumberingSystem object. * @draft ICU 52 */ U_DRAFT int32_t U_EXPORT2 -unumsys_getRadix(UNumberingSystem *unumsys); +unumsys_getRadix(const UNumberingSystem *unumsys); /** - * Returns whether the given UNumberingSystem object is for an algorithmic (not purely decimal) system. - * @param unumsys The UNumberingSystem whose algorithmic status is desired. - * @return TRUE if the specified UNumberingSystem object is for an algorithmic system. + * Get the description string of the specified UNumberingSystem object. For simple + * positional systems this is the ordered string of digits (with length matching + * the radix), e.g. "\u3007\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D" + * for "hanidec"; it would be "0123456789ABCDEF" for hexadecimal. For + * algorithmic systems this is the name of the RBNF ruleset used for formatting, + * e.g. "zh/SpelloutRules/%spellout-cardinal" for "hans" or "%greek-upper" for + * "grek". + * @param unumsys The UNumberingSystem whose description string is desired. + * @param result A pointer to a buffer to receive the description string. + * @param resultLength The maximum size of result. + * @param status A pointer to a UErrorCode to receive any errors. + * @return The total buffer size needed; if greater than resultLength, the + * output was truncated. * @draft ICU 52 */ -U_DRAFT UBool U_EXPORT2 -unumsys_isAlgorithmic(UNumberingSystem *unumsys); +U_DRAFT int32_t U_EXPORT2 +unumsys_getDescription(const UNumberingSystem *unumsys, UChar *result, + int32_t resultLength, UErrorCode *status); #endif /* U_HIDE_DRAFT_API */ diff --git a/icu4c/source/i18n/unumsys.cpp b/icu4c/source/i18n/unumsys.cpp index f8eb6c7d654..aab769dd030 100644 --- a/icu4c/source/i18n/unumsys.cpp +++ b/icu4c/source/i18n/unumsys.cpp @@ -19,6 +19,7 @@ U_NAMESPACE_USE U_CAPI UNumberingSystem* U_EXPORT2 unumsys_open(const char *locale, UErrorCode *status) { + // createInstance returns immediately if status indicates error return (UNumberingSystem*)NumberingSystem::createInstance(Locale(locale), *status); } @@ -26,6 +27,10 @@ unumsys_open(const char *locale, UErrorCode *status) U_CAPI UNumberingSystem* U_EXPORT2 unumsys_openByName(const char *name, UErrorCode *status) { + // createInstanceByName does NOT return immediately if status indicates error + if (U_FAILURE(*status)) { + return NULL; + } return (UNumberingSystem*)NumberingSystem::createInstanceByName(name, *status); } @@ -40,29 +45,42 @@ unumsys_close(UNumberingSystem *unumsys) U_CAPI UEnumeration* U_EXPORT2 unumsys_openAvailableNames(UErrorCode *status) { + // getAvailableNames returns immediately if status indicates error return uenum_openFromStringEnumeration(NumberingSystem::getAvailableNames(*status), status); } U_CAPI const char * U_EXPORT2 -unumsys_getName(UNumberingSystem *unumsys) +unumsys_getName(const UNumberingSystem *unumsys) { return ((NumberingSystem*)unumsys)->getName(); } U_CAPI int32_t U_EXPORT2 -unumsys_getRadix(UNumberingSystem *unumsys) +unumsys_getRadix(const UNumberingSystem *unumsys) { return ((NumberingSystem*)unumsys)->getRadix(); } U_CAPI UBool U_EXPORT2 -unumsys_isAlgorithmic(UNumberingSystem *unumsys) +unumsys_isAlgorithmic(const UNumberingSystem *unumsys) { return ((NumberingSystem*)unumsys)->isAlgorithmic(); } +U_CAPI int32_t U_EXPORT2 +unumsys_getDescription(const UNumberingSystem *unumsys, UChar *result, + int32_t resultLength, UErrorCode *status) +{ + if (U_FAILURE(*status)) { + return -1; + } + // implement + UnicodeString descrip = ((NumberingSystem*)unumsys)->getDescription(); + return descrip.extract(result, resultLength, *status); +} + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/icu4c/source/test/cintltst/cnumtst.c b/icu4c/source/test/cintltst/cnumtst.c index 7898f36e786..5a5694dfc3c 100644 --- a/icu4c/source/test/cintltst/cnumtst.c +++ b/icu4c/source/test/cintltst/cnumtst.c @@ -2289,22 +2289,35 @@ static void TestUFormattable(void) { } typedef struct { - const char * locale; - const char * numsys; + const char* locale; + const char* numsys; int32_t radix; UBool isAlgorithmic; + const UChar* description; } NumSysTestItem; + +static const UChar latnDesc[] = {0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0}; // 0123456789 +static const UChar romanDesc[] = {0x25,0x72,0x6F,0x6D,0x61,0x6E,0x2D,0x75,0x70,0x70,0x65,0x72,0}; // %roman-upper +static const UChar arabDesc[] = {0x0660,0x0661,0x0662,0x0663,0x0664,0x0665,0x0666,0x0667,0x0668,0x0669,0}; // +static const UChar arabextDesc[] = {0x06F0,0x06F1,0x06F2,0x06F3,0x06F4,0x06F5,0x06F6,0x06F7,0x06F8,0x06F9,0}; // +static const UChar hanidecDesc[] = {0x3007,0x4E00,0x4E8C,0x4E09,0x56DB,0x4E94,0x516D,0x4E03,0x516B,0x4E5D,0}; // +static const UChar hantDesc[] = {0x7A,0x68,0x5F,0x48,0x61,0x6E,0x74,0x2F,0x53,0x70,0x65,0x6C,0x6C,0x6F,0x75,0x74, + 0x52,0x75,0x6C,0x65,0x73,0x2F,0x25,0x73,0x70,0x65,0x6C,0x6C,0x6F,0x75,0x74,0x2D, + 0x63,0x61,0x72,0x64,0x69,0x6E,0x61,0x6C,0}; // zh_Hant/SpelloutRules/%spellout-cardinal + static const NumSysTestItem numSysTestItems[] = { - //locale numsys radix isAlgorithmic - { "en", "latn", 10, FALSE }, - { "en@numbers=roman", "roman", 10, TRUE }, - { "en@numbers=finance", "latn", 10, FALSE }, - { "ar", "arab", 10, FALSE }, - { "fa", "arabext", 10, FALSE }, - { "zh_Hant@numbers=traditional", "hant", 10, TRUE }, - { NULL, NULL, 0, FALSE }, + //locale numsys radix isAlgo description + { "en", "latn", 10, FALSE, latnDesc }, + { "en@numbers=roman", "roman", 10, TRUE, romanDesc }, + { "en@numbers=finance", "latn", 10, FALSE, latnDesc }, + { "ar", "arab", 10, FALSE, arabDesc }, + { "fa", "arabext", 10, FALSE, arabextDesc }, + { "zh_Hans@numbers=hanidec", "hanidec", 10, FALSE, hanidecDesc }, + { "zh_Hant@numbers=traditional", "hant", 10, TRUE, hantDesc }, + { NULL, NULL, 0, FALSE, NULL }, }; +enum { kNumSysDescripBufMax = 64 }; static void TestUNumberingSystem(void) { const NumSysTestItem * itemPtr; @@ -2317,13 +2330,18 @@ static void TestUNumberingSystem(void) { status = U_ZERO_ERROR; unumsys = unumsys_open(itemPtr->locale, &status); if ( U_SUCCESS(status) ) { - int32_t radix = unumsys_getRadix(unumsys); + UChar ubuf[kNumSysDescripBufMax]; + int32_t ulen, radix = unumsys_getRadix(unumsys); UBool isAlgorithmic = unumsys_isAlgorithmic(unumsys); numsys = unumsys_getName(unumsys); if ( uprv_strcmp(numsys, itemPtr->numsys) != 0 || radix != itemPtr->radix || !isAlgorithmic != !itemPtr->isAlgorithmic ) { log_err("unumsys name/radix/isAlgorithmic for locale %s, expected %s/%d/%d, got %s/%d/%d\n", itemPtr->locale, itemPtr->numsys, itemPtr->radix, itemPtr->isAlgorithmic, numsys, radix, isAlgorithmic); } + ulen = unumsys_getDescription(unumsys, ubuf, kNumSysDescripBufMax, &status); + if ( U_FAILURE(status) || u_strcmp(ubuf, itemPtr->description) != 0 ) { + log_err("unumsys description for locale %s, description unexpected and/or status %\n", myErrorName(status)); + } unumsys_close(unumsys); } else { log_data_err("unumsys_open for locale %s fails with status %s\n", itemPtr->locale, myErrorName(status)); -- 2.40.0