ICU-2938 add uloc_getDisplayKeywords, uloc_getDisplayKeywordValue, uset_applyPattern

X-SVN-Rev: 13615
This commit is contained in:
Ram Viswanadha 2003-11-07 02:38:19 +00:00
parent ab056703bd
commit c93625a460
5 changed files with 306 additions and 17 deletions

View file

@ -52,14 +52,16 @@ U_CFUNC const char *locale_get_default(void);
/* These strings describe the resources we attempt to load from
the locale ResourceBundle data file.*/
static const char _kLanguages[] = "Languages";
static const char _kScripts[] = "Scripts";
static const char _kCountries[] = "Countries";
static const char _kVariants[] = "Variants";
static const char _kKeys[] = "Keys";
static const char _kLanguages[] = "Languages";
static const char _kScripts[] = "Scripts";
static const char _kCountries[] = "Countries";
static const char _kVariants[] = "Variants";
static const char _kKeys[] = "Keys";
static const char _kTypes[] = "Types";
static const char _kIndexLocaleName[] = "res_index";
static const char _kIndexTag[] = "InstalledLocales";
static const char _kIndexTag[] = "InstalledLocales";
static const char _kCurrency[] = "currency";
static const char _kCurrencies[] = "Currencies";
static char** _installedLocales = NULL;
static int32_t _installedLocalesCount = 0;
@ -1334,7 +1336,8 @@ uloc_getLCID(const char* localeID)
*/
static const UChar *
_res_getTableStringWithFallback(const char *path, const char *locale,
const char *tableKey, const char *itemKey,
const char *tableKey, const char *subTableKey,
const char *itemKey,
int32_t *pLength,
UErrorCode *pErrorCode)
{
@ -1400,7 +1403,14 @@ _res_getTableStringWithFallback(const char *path, const char *locale,
/* try to open the requested item in the table */
errorCode=U_ZERO_ERROR;
item=ures_getStringByKey(&table, itemKey, pLength, &errorCode);
if(subTableKey == NULL){
item=ures_getStringByKey(&table, itemKey, pLength, &errorCode);
}else{
UResourceBundle subTable;
ures_initStackObject(&subTable);
ures_getByKey(&table, subTableKey, &subTable, &errorCode);
item = ures_getStringByKey(&subTable, itemKey, pLength, &errorCode);
}
if(U_SUCCESS(errorCode)) {
/* if the item for the key is empty ... override the explicit fall back set */
if(item[0]==0 && efnLen > 0){
@ -1476,7 +1486,9 @@ _res_getTableStringWithFallback(const char *path, const char *locale,
static int32_t
_getStringOrCopyKey(const char *path, const char *locale,
const char *tableKey, const char *itemKey,
const char *tableKey,
const char* subTableKey,
const char *itemKey,
const char *substitute,
UChar *dest, int32_t destCapacity,
UErrorCode *pErrorCode) {
@ -1496,7 +1508,9 @@ _getStringOrCopyKey(const char *path, const char *locale,
} else {
/* second-level item, use special fallback */
s=_res_getTableStringWithFallback(path, locale,
tableKey, itemKey,
tableKey,
subTableKey,
itemKey,
&length,
pErrorCode);
}
@ -1544,8 +1558,8 @@ uloc_getDisplayLanguage(const char *locale,
}
return _getStringOrCopyKey(NULL, displayLocale,
_kLanguages, localeBuffer,
localeBuffer,
_kLanguages, NULL, localeBuffer,
localeBuffer,
dest, destCapacity,
pErrorCode);
}
@ -1580,12 +1594,15 @@ uloc_getDisplayScript(const char* locale,
}
return _getStringOrCopyKey(NULL, displayLocale,
_kScripts, localeBuffer,
_kScripts, NULL,
localeBuffer,
localeBuffer,
dest, destCapacity,
pErrorCode);
}
U_CAPI int32_t U_EXPORT2
uloc_getDisplayCountry(const char *locale,
const char *displayLocale,
@ -1615,7 +1632,8 @@ uloc_getDisplayCountry(const char *locale,
}
return _getStringOrCopyKey(NULL, displayLocale,
_kCountries, localeBuffer,
_kCountries, NULL,
localeBuffer,
localeBuffer,
dest, destCapacity,
pErrorCode);
@ -1660,7 +1678,8 @@ uloc_getDisplayVariant(const char *locale,
/* pass itemKey=NULL to look for a top-level item */
return _getStringOrCopyKey(NULL, displayLocale,
_kVariants, localeBuffer,
_kVariants, NULL,
localeBuffer,
localeBuffer,
dest, destCapacity,
pErrorCode);
@ -1809,6 +1828,143 @@ uloc_getDisplayName(const char *locale,
return u_terminateUChars(dest, destCapacity, length, pErrorCode);
}
U_CAPI int32_t U_EXPORT2
uloc_getDisplayKeyword(const char* keyword,
const char* displayLocale,
UChar* dest,
int32_t destCapacity,
UErrorCode* status){
/* argument checking */
if(status==NULL || U_FAILURE(*status)) {
return 0;
}
if(destCapacity<0 || (destCapacity>0 && dest==NULL)) {
*status=U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
/* pass itemKey=NULL to look for a top-level item */
return _getStringOrCopyKey(NULL, displayLocale,
_kKeys, NULL,
keyword,
keyword,
dest, destCapacity,
status);
}
/**
* Modify the given locale name by removing the rightmost _-delimited
* element. If there is none, empty the string ("" == root).
* NOTE: The string "root" is not recognized; do not use it.
* @return TRUE if the fallback happened; FALSE if locale is already
* root ("").
*/
static UBool fallback(char *loc) {
UErrorCode status = U_ZERO_ERROR;
if (!*loc) {
return FALSE;
}
uloc_getParent(loc, loc, uprv_strlen(loc), &status);
return TRUE;
}
#define UCURRENCY_DISPLAY_NAME_INDEX 1
U_CAPI int32_t U_EXPORT2
uloc_getDisplayKeywordValue( const char* locale,
const char* keyword,
const char* displayLocale,
UChar* dest,
int32_t destCapacity,
UErrorCode* status){
char loc[ULOC_FULLNAME_CAPACITY*4];
int32_t locLen = 0;
char keywordValue[ULOC_FULLNAME_CAPACITY*4];
int32_t capacity = ULOC_FULLNAME_CAPACITY*4;
int32_t keywordValueLen =0;
/* argument checking */
if(status==NULL || U_FAILURE(*status)) {
return 0;
}
if(destCapacity<0 || (destCapacity>0 && dest==NULL)) {
*status=U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
/* get the keyword value */
keywordValueLen = uloc_getKeywordValue(locale, keyword, keywordValue, capacity, status);
/*
* if the keyword is equal to currency .. then to get the display name
* we need to do the fallback ourselves
*/
if(uprv_stricmp(keyword, _kCurrency)==0){
UErrorCode ec2 = U_ZERO_ERROR;
int32_t dispNameLen = 0;
const UChar *dispName = NULL;
for (;;) {
UResourceBundle* rb = ures_open(NULL, displayLocale, &ec2);
UResourceBundle* curr = ures_getByKey(rb, _kCurrencies, NULL, &ec2);
UResourceBundle* names = ures_getByKey(curr, keywordValue, NULL, &ec2);
dispName = ures_getStringByIndex(names, UCURRENCY_DISPLAY_NAME_INDEX, &dispNameLen, &ec2);
ures_close(names);
ures_close(curr);
ures_close(rb);
/* If we've succeeded we're done. Otherwise, try to fallback.
* If that fails (because we are already at root) then exit.
*/
if (U_SUCCESS(ec2) || !fallback(loc)) {
break;
}
}
if(U_FAILURE(ec2)){
*status = ec2;
return 0;
}
/* now copy the dispName over if not NULL */
if(dispName != NULL){
if(dispNameLen <= destCapacity){
uprv_memcpy(dest, dispName, dispNameLen * U_SIZEOF_UCHAR);
return u_terminateUChars(dest, destCapacity, dispNameLen, status);
}else{
*status = U_BUFFER_OVERFLOW_ERROR;
return dispNameLen;
}
}else{
/* we have not found the display name for the value .. just copy over */
if(keywordValueLen <= destCapacity){
u_charsToUChars(keywordValue, dest, keywordValueLen);
return u_terminateUChars(dest, destCapacity, keywordValueLen, status);
}else{
*status = U_BUFFER_OVERFLOW_ERROR;
return keywordValueLen;
}
}
}else{
return _getStringOrCopyKey(NULL, displayLocale,
_kTypes, keyword,
keywordValue,
keywordValue,
dest, destCapacity,
status);
}
}
static void _load_installedLocales()
{
UBool localesLoaded;

View file

@ -557,7 +557,7 @@ uloc_getDisplayCountry(const char* locale,
/**
* Gets the variant code suitable for display for the specified locale.
* Gets the variant name suitable for display for the specified locale.
*
* @param locale the locale to get the displayable variant code with. NULL may be used to specify the default.
* @param displayLocale Specifies the locale to be used to display the name. In other words,
@ -579,6 +579,79 @@ uloc_getDisplayVariant(const char* locale,
int32_t variantCapacity,
UErrorCode* status);
/**
* Gets the keyword name suitable for display for the specified locale.
* E.g: for the locale string de_DE@collation=PHONEBOOK, this API gets the display
* string for the keyword collation.
* Usage:
* <code>
* UErrorCode status = U_ZERO_ERROR;
* const char* keyword =NULL;
* int32_t keywordLen = 0;
* int32_t keywordCount = 0;
* UChar displayKeyword[256];
* int32_t displayKeywordLen = 0;
* UEnumeration* keywordEnum = uloc_getKeywords("de_DE@collation=PHONEBOOK;calendar=TRADITIONAL", &status);
* for(keywordCount = uenum_count(keywordEnum, &status); keywordCount > 0 ; keywordCount--){
* if(U_FAILURE(status)){
* ...something went wrong so handle the error...
* break;
* }
* // the uenum_next returns NUL terminated string
* keyword = uenum_next(keywordEnum, &keywordLen, &status);
* displayKeywordLen = uloc_getDisplayKeyword(keyword, "en_US", displayKeyword, 256);
* ... do something interesting .....
* }
* uenum_close(keywordEnum);
* </code>
* @param keyword The keyword whose display string needs to be returned.
* @param displayLocale Specifies the locale to be used to display the name. In other words,
* if the locale's language code is "en", passing Locale::getFrench() for
* inLocale would result in "Anglais", while passing Locale::getGerman()
* for inLocale would result in "Englisch". NULL may be used to specify the default.
* @param dest the buffer to which the displayable keyword should be written.
* @param destCapacity The size of the buffer (number of UChars). If it is 0, then
* dest may be NULL and the function will only return the length of the
* result without writing any of the result string (pre-flighting).
* @param status error information if retrieving the displayable string failed.
* Should not be NULL and should not indicate failure on entry.
* @return the actual buffer size needed for the displayable variant code.
* @see #uloc_getKeywords
* @draft ICU 2.8
*/
U_CAPI int32_t U_EXPORT2
uloc_getDisplayKeyword(const char* keyword,
const char* displayLocale,
UChar* dest,
int32_t destCapacity,
UErrorCode* status);
/**
* Gets the value of the keyword suitable for display for the specified locale.
* E.g: for the locale string de_DE@collation=PHONEBOOK, this API gets the display
* string for PHONEBOOK, in the display locale, when "collation" is specified as the keyword.
*
* @param locale The locale to get the displayable variant code with. NULL may be used to specify the default.
* @param keyword The keyword for whose value should be used.
* @param displayLocale Specifies the locale to be used to display the name. In other words,
* if the locale's language code is "en", passing Locale::getFrench() for
* inLocale would result in "Anglais", while passing Locale::getGerman()
* for inLocale would result in "Englisch". NULL may be used to specify the default.
* @param dest the buffer to which the displayable keyword should be written.
* @param destCapacity The size of the buffer (number of UChars). If it is 0, then
* dest may be NULL and the function will only return the length of the
* result without writing any of the result string (pre-flighting).
* @param status error information if retrieving the displayable string failed.
* Should not be NULL and must not indicate failure on entry.
* @return the actual buffer size needed for the displayable variant code.
* @draft ICU 2.8
*/
U_CAPI int32_t U_EXPORT2
uloc_getDisplayKeywordValue( const char* locale,
const char* keyword,
const char* displayLocale,
UChar* dest,
int32_t destCapacity,
UErrorCode* status);
/**
* Gets the full name suitable for display for the specified locale.
*

View file

@ -451,6 +451,7 @@ public:
* @param pattern a string specifying what characters are in the set
* @param status returns <code>U_ILLEGAL_ARGUMENT_ERROR</code> if the pattern
* contains a syntax error.
* <em> Empties the set passed before applying the pattern.<em>
* @return a reference to this
* @stable ICU 2.0
*/
@ -468,6 +469,7 @@ public:
* values and stand-ins to UnicodeSets; may be NULL
* @param status returns <code>U_ILLEGAL_ARGUMENT_ERROR</code> if the pattern
* contains a syntax error.
*<em> Empties the set passed before applying the pattern.<em>
* @return a reference to this
* @internal
*/
@ -486,6 +488,7 @@ public:
* following the closing ']', and a StringBuffer containing a
* pairs list for the parsed pattern is returned. This method calls
* itself recursively to parse embedded subpatterns.
*<em> Empties the set passed before applying the pattern.<em>
*
* @param pattern the string containing the pattern to be parsed.
* The portion of the string from pos.getIndex(), which must be a

View file

@ -28,6 +28,7 @@
#define __USET_H__
#include "unicode/utypes.h"
#include "unicode/umisc.h"
#ifndef UCNV_H
struct USet;
@ -154,6 +155,32 @@ uset_openPatternOptions(const UChar* pattern, int32_t patternLength,
U_CAPI void U_EXPORT2
uset_close(USet* set);
/**
* Modifies the set to represent the set specified by the given
* pattern. See the UnicodeSet class description for the syntax of
* the pattern language. See also the User Guide chapter about UnicodeSet.
* <em> Empties the set passed before applying the pattern.<em>
* @param set The set to which the pattern is to be applied.
* @param pattern A pointer to UChar string specifying what characters are in the set.
* The character at pattern[0] must be a '['.
* @param patternLength The length of the UChar string. -1 if NUL terminated.
* @param options A bitmask for options to apply to the pattern.
* Valid options are USET_IGNORE_SPACE and USET_CASE_INSENSITIVE.
* @param status Returns an error if the pattern cannot be parsed.
* @return Upon successful parse, the value is either
* the index of the character after the closing ']'
* of the parsed pattern.
* If the status code indicates failure, then the return value
* is the index of the error in the source.
*
* @draft ICU 2.8
*/
U_CAPI int32_t U_EXPORT2
uset_applyPattern(USet *set,
const UChar *pattern, int32_t patternLength,
uint32_t options,
UErrorCode *status);
/**
* Returns a string representation of this set. If the result of
* calling this function is passed to a uset_openPattern(), it

View file

@ -27,6 +27,7 @@
#include "unicode/uniset.h"
#include "cmemory.h"
#include "unicode/ustring.h"
#include "unicode/parsepos.h"
U_CAPI USet* U_EXPORT2
uset_open(UChar32 start, UChar32 end) {
@ -78,6 +79,35 @@ uset_close(USet* set) {
delete (UnicodeSet*) set;
}
U_CAPI int32_t U_EXPORT2
uset_applyPattern(USet *set,
const UChar *pattern, int32_t patternLength,
uint32_t options,
UErrorCode *status){
// status code needs to be checked since we
// dereference it
if(status == NULL || U_FAILURE(*status)){
return 0;
}
// check only the set paramenter
// if pattern is NULL or null terminate
// UnicodeString constructor takes care of it
if(set == NULL){
*status = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
UnicodeString pat(pattern, patternLength);
ParsePosition pos;
((UnicodeSet*) set)->applyPattern(pat, pos, options, NULL, *status);
return pos.getIndex();
}
U_CAPI int32_t U_EXPORT2
uset_toPattern(const USet* set,
UChar* result, int32_t resultCapacity,