mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-13 08:53:20 +00:00
ICU-2938 add uloc_getDisplayKeywords, uloc_getDisplayKeywordValue, uset_applyPattern
X-SVN-Rev: 13615
This commit is contained in:
parent
ab056703bd
commit
c93625a460
5 changed files with 306 additions and 17 deletions
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue