ICU-7302 Reading bcp47 key/type mapping data from the new resources in ICU4C.

X-SVN-Rev: 27516
This commit is contained in:
Yoshito Umaoka 2010-02-09 03:51:54 +00:00
parent 16c90bb9d5
commit 572475f613
2 changed files with 78 additions and 46 deletions

View File

@ -1,6 +1,6 @@
/* /*
********************************************************************** **********************************************************************
* Copyright (C) 2009, International Business Machines * Copyright (C) 2009-2010, International Business Machines
* Corporation and others. All Rights Reserved. * Corporation and others. All Rights Reserved.
********************************************************************** **********************************************************************
*/ */
@ -543,8 +543,10 @@ _initializeULanguageTag(ULanguageTag* langtag) {
langtag->privateuse = EMPTY; langtag->privateuse = EMPTY;
} }
#define SUPPLEMENTAL "supplementalData" #define KEYTYPEDATA "keyTypeData"
#define BCP47MAPPINGS "bcp47KeywordMappings" #define KEYMAP "keyMap"
#define TYPEMAP "typeMap"
#define TYPEALIAS "typeAlias"
#define MAX_BCP47_SUBTAG_LEN 9 /* including null terminator */ #define MAX_BCP47_SUBTAG_LEN 9 /* including null terminator */
#define MAX_LDML_KEY_LEN 22 #define MAX_LDML_KEY_LEN 22
#define MAX_LDML_TYPE_LEN 32 #define MAX_LDML_TYPE_LEN 32
@ -580,9 +582,8 @@ _ldmlKeyToBCP47(const char* key, int32_t keyLen,
keyBuf[i] = uprv_tolower(keyBuf[i]); keyBuf[i] = uprv_tolower(keyBuf[i]);
} }
rb = ures_openDirect(NULL, SUPPLEMENTAL, status); rb = ures_openDirect(NULL, KEYTYPEDATA, status);
ures_getByKey(rb, BCP47MAPPINGS, rb, status); ures_getByKey(rb, KEYMAP, rb, status);
ures_getByKey(rb, "key", rb, status);
if (U_FAILURE(*status)) { if (U_FAILURE(*status)) {
ures_close(rb); ures_close(rb);
@ -623,7 +624,7 @@ _bcp47ToLDMLKey(const char* bcpKey, int32_t bcpKeyLen,
int32_t resultLen = 0; int32_t resultLen = 0;
int32_t i; int32_t i;
const char *resKey = NULL; const char *resKey = NULL;
UResourceBundle *keyMap; UResourceBundle *mapData;
if (bcpKeyLen < 0) { if (bcpKeyLen < 0) {
bcpKeyLen = (int32_t)uprv_strlen(bcpKey); bcpKeyLen = (int32_t)uprv_strlen(bcpKey);
@ -642,21 +643,20 @@ _bcp47ToLDMLKey(const char* bcpKey, int32_t bcpKeyLen,
bcpKeyBuf[i] = uprv_tolower(bcpKeyBuf[i]); bcpKeyBuf[i] = uprv_tolower(bcpKeyBuf[i]);
} }
rb = ures_openDirect(NULL, SUPPLEMENTAL, status); rb = ures_openDirect(NULL, KEYTYPEDATA, status);
ures_getByKey(rb, BCP47MAPPINGS, rb, status); ures_getByKey(rb, KEYMAP, rb, status);
ures_getByKey(rb, "key", rb, status);
if (U_FAILURE(*status)) { if (U_FAILURE(*status)) {
ures_close(rb); ures_close(rb);
return 0; return 0;
} }
keyMap = ures_getNextResource(rb, NULL, status); mapData = ures_getNextResource(rb, NULL, status);
while (U_SUCCESS(*status)) { while (U_SUCCESS(*status)) {
const UChar *uBcpKey; const UChar *uBcpKey;
char tmpBcpKeyBuf[MAX_BCP47_SUBTAG_LEN]; char tmpBcpKeyBuf[MAX_BCP47_SUBTAG_LEN];
int32_t tmpBcpKeyLen; int32_t tmpBcpKeyLen;
uBcpKey = ures_getString(keyMap, &tmpBcpKeyLen, status); uBcpKey = ures_getString(mapData, &tmpBcpKeyLen, status);
if (U_FAILURE(*status)) { if (U_FAILURE(*status)) {
break; break;
} }
@ -664,16 +664,16 @@ _bcp47ToLDMLKey(const char* bcpKey, int32_t bcpKeyLen,
tmpBcpKeyBuf[tmpBcpKeyLen] = 0; tmpBcpKeyBuf[tmpBcpKeyLen] = 0;
if (uprv_strcmp(bcpKeyBuf, tmpBcpKeyBuf) == 0) { if (uprv_strcmp(bcpKeyBuf, tmpBcpKeyBuf) == 0) {
/* found a matching BCP47 key */ /* found a matching BCP47 key */
resKey = ures_getKey(keyMap); resKey = ures_getKey(mapData);
resultLen = (int32_t)uprv_strlen(resKey); resultLen = (int32_t)uprv_strlen(resKey);
break; break;
} }
if (!ures_hasNext(rb)) { if (!ures_hasNext(rb)) {
break; break;
} }
ures_getNextResource(rb, keyMap, status); ures_getNextResource(rb, mapData, status);
} }
ures_close(keyMap); ures_close(mapData);
ures_close(rb); ures_close(rb);
if (U_FAILURE(*status)) { if (U_FAILURE(*status)) {
@ -694,16 +694,15 @@ _ldmlTypeToBCP47(const char* key, int32_t keyLen,
const char* type, int32_t typeLen, const char* type, int32_t typeLen,
char* bcpType, int32_t bcpTypeCapacity, char* bcpType, int32_t bcpTypeCapacity,
UErrorCode *status) { UErrorCode *status) {
UResourceBundle *rb, *keyTypeData, *typeMapForKey;
UResourceBundle *rb;
char keyBuf[MAX_LDML_KEY_LEN]; char keyBuf[MAX_LDML_KEY_LEN];
char typeBuf[MAX_LDML_TYPE_LEN]; char typeBuf[MAX_LDML_TYPE_LEN];
char bcpTypeBuf[MAX_BCP47_SUBTAG_LEN]; char bcpTypeBuf[MAX_BCP47_SUBTAG_LEN];
int32_t resultLen = 0; int32_t resultLen = 0;
int32_t i; int32_t i;
UErrorCode tmpStatus = U_ZERO_ERROR; UErrorCode tmpStatus = U_ZERO_ERROR;
const UChar *uBcpType; const UChar *uBcpType, *uCanonicalType;
int32_t bcpTypeLen; int32_t bcpTypeLen, canonicalTypeLen;
UBool isTimezone = FALSE; UBool isTimezone = FALSE;
if (keyLen < 0) { if (keyLen < 0) {
@ -732,30 +731,59 @@ _ldmlTypeToBCP47(const char* key, int32_t keyLen,
*status = U_ILLEGAL_ARGUMENT_ERROR; *status = U_ILLEGAL_ARGUMENT_ERROR;
return 0; return 0;
} }
uprv_memcpy(typeBuf, type, typeLen);
typeBuf[typeLen] = 0;
if (isTimezone) {
/* replace '/' with ':' */
for (i = 0; i < typeLen; i++) { for (i = 0; i < typeLen; i++) {
if (isTimezone && typeBuf[i] == '/') { if (*(type + i) == '/') {
typeBuf[i] = ':'; typeBuf[i] = ':';
} else { } else {
typeBuf[i] = uprv_tolower(typeBuf[i]); typeBuf[i] = *(type + i);
} }
} }
typeBuf[typeLen] = 0;
type = &typeBuf[0];
}
rb = ures_openDirect(NULL, SUPPLEMENTAL, status); keyTypeData = ures_openDirect(NULL, KEYTYPEDATA, status);
ures_getByKey(rb, BCP47MAPPINGS, rb, status); rb = ures_getByKey(keyTypeData, TYPEMAP, NULL, status);
if (U_FAILURE(*status)) { if (U_FAILURE(*status)) {
ures_close(rb); ures_close(rb);
ures_close(keyTypeData);
return 0; return 0;
} }
ures_getByKey(rb, keyBuf, rb, &tmpStatus); typeMapForKey = ures_getByKey(rb, keyBuf, NULL, &tmpStatus);
uBcpType = ures_getStringByKey(rb, typeBuf, &bcpTypeLen, &tmpStatus); uBcpType = ures_getStringByKey(typeMapForKey, type, &bcpTypeLen, &tmpStatus);
if (U_SUCCESS(tmpStatus)) { if (U_SUCCESS(tmpStatus)) {
u_UCharsToChars(uBcpType, bcpTypeBuf, bcpTypeLen); u_UCharsToChars(uBcpType, bcpTypeBuf, bcpTypeLen);
resultLen = bcpTypeLen; resultLen = bcpTypeLen;
} else if (tmpStatus == U_MISSING_RESOURCE_ERROR) { } else if (tmpStatus == U_MISSING_RESOURCE_ERROR) {
/* is this type alias? */
tmpStatus = U_ZERO_ERROR;
ures_getByKey(keyTypeData, TYPEALIAS, rb, &tmpStatus);
ures_getByKey(rb, keyBuf, rb, &tmpStatus);
uCanonicalType = ures_getStringByKey(rb, type, &canonicalTypeLen, &tmpStatus);
if (U_SUCCESS(tmpStatus)) {
u_UCharsToChars(uCanonicalType, typeBuf, canonicalTypeLen);
if (isTimezone) {
/* replace '/' with ':' */
for (i = 0; i < canonicalTypeLen; i++) {
if (typeBuf[i] == '/') {
typeBuf[i] = ':';
}
}
}
typeBuf[canonicalTypeLen] = 0;
/* look up the canonical type */
uBcpType = ures_getStringByKey(typeMapForKey, typeBuf, &bcpTypeLen, &tmpStatus);
if (U_SUCCESS(tmpStatus)) {
u_UCharsToChars(uBcpType, bcpTypeBuf, bcpTypeLen);
resultLen = bcpTypeLen;
}
}
if (tmpStatus == U_MISSING_RESOURCE_ERROR) {
if (_isLDMLType(type, typeLen)) { if (_isLDMLType(type, typeLen)) {
uprv_memcpy(bcpTypeBuf, type, typeLen); uprv_memcpy(bcpTypeBuf, type, typeLen);
resultLen = typeLen; resultLen = typeLen;
@ -763,10 +791,13 @@ _ldmlTypeToBCP47(const char* key, int32_t keyLen,
/* mapping not availabe */ /* mapping not availabe */
*status = U_ILLEGAL_ARGUMENT_ERROR; *status = U_ILLEGAL_ARGUMENT_ERROR;
} }
}
} else { } else {
*status = tmpStatus; *status = tmpStatus;
} }
ures_close(rb); ures_close(rb);
ures_close(typeMapForKey);
ures_close(keyTypeData);
if (U_FAILURE(*status)) { if (U_FAILURE(*status)) {
return 0; return 0;
@ -787,7 +818,7 @@ _bcp47ToLDMLType(const char* key, int32_t keyLen,
int32_t resultLen = 0; int32_t resultLen = 0;
int32_t i; int32_t i;
const char *resType = NULL; const char *resType = NULL;
UResourceBundle *typeMap; UResourceBundle *mapData;
UErrorCode tmpStatus = U_ZERO_ERROR; UErrorCode tmpStatus = U_ZERO_ERROR;
int32_t copyLen; int32_t copyLen;
@ -826,21 +857,21 @@ _bcp47ToLDMLType(const char* key, int32_t keyLen,
bcpTypeBuf[i] = uprv_tolower(bcpTypeBuf[i]); bcpTypeBuf[i] = uprv_tolower(bcpTypeBuf[i]);
} }
rb = ures_openDirect(NULL, SUPPLEMENTAL, status); rb = ures_openDirect(NULL, KEYTYPEDATA, status);
ures_getByKey(rb, BCP47MAPPINGS, rb, status); ures_getByKey(rb, TYPEMAP, rb, status);
if (U_FAILURE(*status)) { if (U_FAILURE(*status)) {
ures_close(rb); ures_close(rb);
return 0; return 0;
} }
ures_getByKey(rb, keyBuf, rb, &tmpStatus); ures_getByKey(rb, keyBuf, rb, &tmpStatus);
typeMap = ures_getNextResource(rb, NULL, &tmpStatus); mapData = ures_getNextResource(rb, NULL, &tmpStatus);
while (U_SUCCESS(tmpStatus)) { while (U_SUCCESS(tmpStatus)) {
const UChar *uBcpType; const UChar *uBcpType;
char tmpBcpTypeBuf[MAX_BCP47_SUBTAG_LEN]; char tmpBcpTypeBuf[MAX_BCP47_SUBTAG_LEN];
int32_t tmpBcpTypeLen; int32_t tmpBcpTypeLen;
uBcpType = ures_getString(typeMap, &tmpBcpTypeLen, &tmpStatus); uBcpType = ures_getString(mapData, &tmpBcpTypeLen, &tmpStatus);
if (U_FAILURE(tmpStatus)) { if (U_FAILURE(tmpStatus)) {
break; break;
} }
@ -848,16 +879,16 @@ _bcp47ToLDMLType(const char* key, int32_t keyLen,
tmpBcpTypeBuf[tmpBcpTypeLen] = 0; tmpBcpTypeBuf[tmpBcpTypeLen] = 0;
if (uprv_strcmp(bcpTypeBuf, tmpBcpTypeBuf) == 0) { if (uprv_strcmp(bcpTypeBuf, tmpBcpTypeBuf) == 0) {
/* found a matching BCP47 type */ /* found a matching BCP47 type */
resType = ures_getKey(typeMap); resType = ures_getKey(mapData);
resultLen = (int32_t)uprv_strlen(resType); resultLen = (int32_t)uprv_strlen(resType);
break; break;
} }
if (!ures_hasNext(rb)) { if (!ures_hasNext(rb)) {
break; break;
} }
ures_getNextResource(rb, typeMap, &tmpStatus); ures_getNextResource(rb, mapData, &tmpStatus);
} }
ures_close(typeMap); ures_close(mapData);
ures_close(rb); ures_close(rb);
if (U_FAILURE(tmpStatus) && tmpStatus != U_MISSING_RESOURCE_ERROR) { if (U_FAILURE(tmpStatus) && tmpStatus != U_MISSING_RESOURCE_ERROR) {

View File

@ -1,6 +1,6 @@
/******************************************************************** /********************************************************************
* COPYRIGHT: * COPYRIGHT:
* Copyright (c) 1997-2009, International Business Machines Corporation and * Copyright (c) 1997-2010, International Business Machines Corporation and
* others. All Rights Reserved. * others. All Rights Reserved.
********************************************************************/ ********************************************************************/
/***************************************************************************** /*****************************************************************************
@ -5410,6 +5410,7 @@ const char* const locale_to_langtag[][3] = {
{"de@collation=phonebook;calendar=gregorian", "de-u-ca-gregory-co-phonebk", "de-u-ca-gregory-co-phonebk"}, {"de@collation=phonebook;calendar=gregorian", "de-u-ca-gregory-co-phonebk", "de-u-ca-gregory-co-phonebk"},
{"th@numbers=thai;z=extz;x=priv-use;a=exta", "th-a-exta-u-nu-thai-z-extz-x-priv-use", "th-a-exta-u-nu-thai-z-extz-x-priv-use"}, {"th@numbers=thai;z=extz;x=priv-use;a=exta", "th-a-exta-u-nu-thai-z-extz-x-priv-use", "th-a-exta-u-nu-thai-z-extz-x-priv-use"},
{"en@timezone=America/New_York;calendar=japanese", "en-u-ca-japanese-tz-usnyc", "en-u-ca-japanese-tz-usnyc"}, {"en@timezone=America/New_York;calendar=japanese", "en-u-ca-japanese-tz-usnyc", "en-u-ca-japanese-tz-usnyc"},
{"en@timezone=US/Eastern", "en-u-tz-usnyc", "en-u-tz-usnyc"},
{"en@x=x-y-z;a=a-b-c", "en-x-x-y-z", NULL}, {"en@x=x-y-z;a=a-b-c", "en-x-x-y-z", NULL},
{"it@collation=badcollationtype;colStrength=identical;cu=usd-eur", "it-u-ks-identic", NULL}, {"it@collation=badcollationtype;colStrength=identical;cu=usd-eur", "it-u-ks-identic", NULL},
{NULL, NULL, NULL} {NULL, NULL, NULL}
@ -5504,7 +5505,7 @@ static const struct {
{"fr-u-nu-latn-cu-eur", "fr@currency=eur;numbers=latn", 19}, {"fr-u-nu-latn-cu-eur", "fr@currency=eur;numbers=latn", 19},
{"de-k-kext-u-co-phonebk-nu-latn", "de@collation=phonebook;k=kext;numbers=latn", 30}, {"de-k-kext-u-co-phonebk-nu-latn", "de@collation=phonebook;k=kext;numbers=latn", 30},
{"ja-u-cu-jpy-ca-jp", "ja@currency=jpy", 11}, {"ja-u-cu-jpy-ca-jp", "ja@currency=jpy", 11},
{"en-us-u-tz-usnyc", "en_US@timezone=america/new_york", 16}, {"en-us-u-tz-usnyc", "en_US@timezone=America/New_York", 16},
{"und-a-abc-def", "und@a=abc-def", 13}, {"und-a-abc-def", "und@a=abc-def", 13},
{"zh-u-ca-chinese-x-u-ca-chinese", "zh@calendar=chinese;x=u-ca-chinese", 30}, {"zh-u-ca-chinese-x-u-ca-chinese", "zh@calendar=chinese;x=u-ca-chinese", 30},
{NULL, NULL, 0} {NULL, NULL, 0}