mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-07 06:25:30 +00:00
ICU-20169 Use smart pointers in all locale code instead of u*_close().
Doing this consistently first will make it easier to then clean up resource management and error handling later.
This commit is contained in:
parent
47ecbc4915
commit
91d38d14e8
7 changed files with 81 additions and 84 deletions
|
@ -125,7 +125,6 @@ static UBool U_CALLCONV uloc_cleanup(void) {
|
|||
// via the initOnce mechanism.
|
||||
|
||||
static void U_CALLCONV loadInstalledLocales() {
|
||||
UResourceBundle *indexLocale = NULL;
|
||||
UResourceBundle installed;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t i = 0;
|
||||
|
@ -136,9 +135,14 @@ static void U_CALLCONV loadInstalledLocales() {
|
|||
|
||||
_installedLocalesCount = 0;
|
||||
ures_initStackObject(&installed);
|
||||
indexLocale = ures_openDirect(NULL, _kIndexLocaleName, &status);
|
||||
ures_getByKey(indexLocale, _kIndexTag, &installed, &status);
|
||||
|
||||
|
||||
icu::LocalUResourceBundlePointer indexLocale(ures_openDirect(NULL, _kIndexLocaleName, &status));
|
||||
|
||||
// Automatically call ures_close() on this when it goes out of scope.
|
||||
icu::LocalUResourceBundlePointer installedCloser(&installed);
|
||||
|
||||
ures_getByKey(indexLocale.getAlias(), _kIndexTag, &installed, &status);
|
||||
|
||||
if(U_SUCCESS(status)) {
|
||||
localeCount = ures_getSize(&installed);
|
||||
_installedLocales = (char **) uprv_malloc(sizeof(char*) * (localeCount+1));
|
||||
|
@ -152,8 +156,6 @@ static void U_CALLCONV loadInstalledLocales() {
|
|||
ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
|
||||
}
|
||||
}
|
||||
ures_close(&installed);
|
||||
ures_close(indexLocale);
|
||||
}
|
||||
|
||||
static void _load_installedLocales()
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "unicode/utypes.h"
|
||||
#include "unicode/brkiter.h"
|
||||
#include "unicode/locid.h"
|
||||
#include "unicode/uenum.h"
|
||||
#include "unicode/uloc.h"
|
||||
#include "unicode/ures.h"
|
||||
#include "unicode/ustring.h"
|
||||
|
@ -306,14 +307,11 @@ _getStringOrCopyKey(const char *path, const char *locale,
|
|||
|
||||
if(itemKey==NULL) {
|
||||
/* top-level item: normal resource bundle access */
|
||||
UResourceBundle *rb;
|
||||
|
||||
rb=ures_open(path, locale, pErrorCode);
|
||||
icu::LocalUResourceBundlePointer rb(ures_open(path, locale, pErrorCode));
|
||||
|
||||
if(U_SUCCESS(*pErrorCode)) {
|
||||
s=ures_getStringByKey(rb, tableKey, &length, pErrorCode);
|
||||
s=ures_getStringByKey(rb.getAlias(), tableKey, &length, pErrorCode);
|
||||
/* see comment about closing rb near "return item;" in _res_getTableStringWithFallback() */
|
||||
ures_close(rb);
|
||||
}
|
||||
} else {
|
||||
/* Language code should not be a number. If it is, set the error code. */
|
||||
|
@ -510,15 +508,14 @@ uloc_getDisplayName(const char *locale,
|
|||
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UResourceBundle* locbundle=ures_open(U_ICUDATA_LANG, displayLocale, &status);
|
||||
UResourceBundle* dspbundle=ures_getByKeyWithFallback(locbundle, _kLocaleDisplayPattern,
|
||||
NULL, &status);
|
||||
|
||||
separator=ures_getStringByKeyWithFallback(dspbundle, _kSeparator, &sepLen, &status);
|
||||
pattern=ures_getStringByKeyWithFallback(dspbundle, _kPattern, &patLen, &status);
|
||||
icu::LocalUResourceBundlePointer locbundle(
|
||||
ures_open(U_ICUDATA_LANG, displayLocale, &status));
|
||||
icu::LocalUResourceBundlePointer dspbundle(
|
||||
ures_getByKeyWithFallback(locbundle.getAlias(), _kLocaleDisplayPattern, NULL, &status));
|
||||
|
||||
ures_close(dspbundle);
|
||||
ures_close(locbundle);
|
||||
separator=ures_getStringByKeyWithFallback(dspbundle.getAlias(), _kSeparator, &sepLen, &status);
|
||||
pattern=ures_getStringByKeyWithFallback(dspbundle.getAlias(), _kPattern, &patLen, &status);
|
||||
}
|
||||
|
||||
/* If we couldn't find any data, then use the defaults */
|
||||
|
@ -586,7 +583,7 @@ uloc_getDisplayName(const char *locale,
|
|||
int32_t langPos=0; /* position in output of language substitution */
|
||||
int32_t restLen=0; /* length of 'everything else' substitution */
|
||||
int32_t restPos=0; /* position in output of 'everything else' substitution */
|
||||
UEnumeration* kenum = NULL; /* keyword enumeration */
|
||||
icu::LocalUEnumerationPointer kenum; /* keyword enumeration */
|
||||
|
||||
/* prefix of pattern, extremely likely to be empty */
|
||||
if(sub0Pos) {
|
||||
|
@ -639,12 +636,11 @@ uloc_getDisplayName(const char *locale,
|
|||
len=uloc_getDisplayVariant(locale, displayLocale, p, cap, pErrorCode);
|
||||
break;
|
||||
case 3:
|
||||
kenum = uloc_openKeywords(locale, pErrorCode);
|
||||
kenum.adoptInstead(uloc_openKeywords(locale, pErrorCode));
|
||||
U_FALLTHROUGH;
|
||||
default: {
|
||||
const char* kw=uenum_next(kenum, &len, pErrorCode);
|
||||
const char* kw=uenum_next(kenum.getAlias(), &len, pErrorCode);
|
||||
if (kw == NULL) {
|
||||
uenum_close(kenum);
|
||||
len=0; /* mark that we didn't add a component */
|
||||
subdone=TRUE;
|
||||
} else {
|
||||
|
@ -832,18 +828,16 @@ uloc_getDisplayKeywordValue( const char* locale,
|
|||
|
||||
int32_t dispNameLen = 0;
|
||||
const UChar *dispName = NULL;
|
||||
|
||||
UResourceBundle *bundle = ures_open(U_ICUDATA_CURR, displayLocale, status);
|
||||
UResourceBundle *currencies = ures_getByKey(bundle, _kCurrencies, NULL, status);
|
||||
UResourceBundle *currency = ures_getByKeyWithFallback(currencies, keywordValue, NULL, status);
|
||||
|
||||
dispName = ures_getStringByIndex(currency, UCURRENCY_DISPLAY_NAME_INDEX, &dispNameLen, status);
|
||||
|
||||
/*close the bundles */
|
||||
ures_close(currency);
|
||||
ures_close(currencies);
|
||||
ures_close(bundle);
|
||||
|
||||
|
||||
icu::LocalUResourceBundlePointer bundle(
|
||||
ures_open(U_ICUDATA_CURR, displayLocale, status));
|
||||
icu::LocalUResourceBundlePointer currencies(
|
||||
ures_getByKey(bundle.getAlias(), _kCurrencies, NULL, status));
|
||||
icu::LocalUResourceBundlePointer currency(
|
||||
ures_getByKeyWithFallback(currencies.getAlias(), keywordValue, NULL, status));
|
||||
|
||||
dispName = ures_getStringByIndex(currency.getAlias(), UCURRENCY_DISPLAY_NAME_INDEX, &dispNameLen, status);
|
||||
|
||||
if(U_FAILURE(*status)){
|
||||
if(*status == U_MISSING_RESOURCE_ERROR){
|
||||
/* we just want to write the value over if nothing is available */
|
||||
|
|
|
@ -50,9 +50,9 @@ findLikelySubtags(const char* localeID,
|
|||
int32_t resLen = 0;
|
||||
const UChar* s = NULL;
|
||||
UErrorCode tmpErr = U_ZERO_ERROR;
|
||||
UResourceBundle* subtags = ures_openDirect(NULL, "likelySubtags", &tmpErr);
|
||||
icu::LocalUResourceBundlePointer subtags(ures_openDirect(NULL, "likelySubtags", &tmpErr));
|
||||
if (U_SUCCESS(tmpErr)) {
|
||||
s = ures_getStringByKey(subtags, localeID, &resLen, &tmpErr);
|
||||
s = ures_getStringByKey(subtags.getAlias(), localeID, &resLen, &tmpErr);
|
||||
|
||||
if (U_FAILURE(tmpErr)) {
|
||||
/*
|
||||
|
@ -71,8 +71,6 @@ findLikelySubtags(const char* localeID,
|
|||
u_UCharsToChars(s, buffer, resLen + 1);
|
||||
result = buffer;
|
||||
}
|
||||
|
||||
ures_close(subtags);
|
||||
} else {
|
||||
*err = tmpErr;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ uloc_getTableStringWithFallback(const char *path, const char *locale,
|
|||
UErrorCode *pErrorCode)
|
||||
{
|
||||
/* char localeBuffer[ULOC_FULLNAME_CAPACITY*4];*/
|
||||
UResourceBundle *rb=NULL, table, subTable;
|
||||
UResourceBundle table, subTable;
|
||||
const UChar *item=NULL;
|
||||
UErrorCode errorCode;
|
||||
char explicitFallbackName[ULOC_FULLNAME_CAPACITY] = {0};
|
||||
|
@ -59,7 +59,11 @@ uloc_getTableStringWithFallback(const char *path, const char *locale,
|
|||
* this falls back through the locale's chain to root
|
||||
*/
|
||||
errorCode=U_ZERO_ERROR;
|
||||
rb=ures_open(path, locale, &errorCode);
|
||||
icu::LocalUResourceBundlePointer rb(ures_open(path, locale, &errorCode));
|
||||
|
||||
// Automatically call ures_close() on these when they go out of scope.
|
||||
icu::LocalUResourceBundlePointer tableCloser(&table);
|
||||
icu::LocalUResourceBundlePointer subTableCloser(&subTable);
|
||||
|
||||
if(U_FAILURE(errorCode)) {
|
||||
/* total failure, not even root could be opened */
|
||||
|
@ -75,7 +79,7 @@ uloc_getTableStringWithFallback(const char *path, const char *locale,
|
|||
for(;;){
|
||||
ures_initStackObject(&table);
|
||||
ures_initStackObject(&subTable);
|
||||
ures_getByKeyWithFallback(rb, tableKey, &table, &errorCode);
|
||||
ures_getByKeyWithFallback(rb.getAlias(), tableKey, &table, &errorCode);
|
||||
|
||||
if (subTableKey != NULL) {
|
||||
/*
|
||||
|
@ -135,8 +139,7 @@ uloc_getTableStringWithFallback(const char *path, const char *locale,
|
|||
*pErrorCode = U_INTERNAL_PROGRAM_ERROR;
|
||||
break;
|
||||
}
|
||||
ures_close(rb);
|
||||
rb = ures_open(path, explicitFallbackName, &errorCode);
|
||||
rb.adoptInstead(ures_open(path, explicitFallbackName, &errorCode));
|
||||
if(U_FAILURE(errorCode)){
|
||||
*pErrorCode = errorCode;
|
||||
break;
|
||||
|
@ -146,10 +149,7 @@ uloc_getTableStringWithFallback(const char *path, const char *locale,
|
|||
break;
|
||||
}
|
||||
}
|
||||
/* done with the locale string - ready to close table and rb */
|
||||
ures_close(&subTable);
|
||||
ures_close(&table);
|
||||
ures_close(rb);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#if !UCONFIG_NO_SERVICE || !UCONFIG_NO_TRANSLITERATION
|
||||
|
||||
#include "unicode/resbund.h"
|
||||
#include "unicode/uenum.h"
|
||||
#include "cmemory.h"
|
||||
#include "ustrfmt.h"
|
||||
#include "locutil.h"
|
||||
|
@ -229,15 +230,14 @@ LocaleUtility::getAvailableLocaleNames(const UnicodeString& bundleID)
|
|||
CharString cbundleID;
|
||||
cbundleID.appendInvariantChars(bundleID, status);
|
||||
const char* path = cbundleID.isEmpty() ? NULL : cbundleID.data();
|
||||
UEnumeration *uenum = ures_openAvailableLocales(path, &status);
|
||||
icu::LocalUEnumerationPointer uenum(ures_openAvailableLocales(path, &status));
|
||||
for (;;) {
|
||||
const UChar* id = uenum_unext(uenum, NULL, &status);
|
||||
const UChar* id = uenum_unext(uenum.getAlias(), NULL, &status);
|
||||
if (id == NULL) {
|
||||
break;
|
||||
}
|
||||
htp->put(UnicodeString(id), (void*)htp, status);
|
||||
}
|
||||
uenum_close(uenum);
|
||||
if (U_FAILURE(status)) {
|
||||
delete htp;
|
||||
return NULL;
|
||||
|
|
|
@ -36,13 +36,8 @@ typedef enum {
|
|||
typedef struct LocExtKeyData {
|
||||
const char* legacyId;
|
||||
const char* bcpId;
|
||||
UHashtable* typeMap;
|
||||
icu::LocalUHashtablePointer typeMap;
|
||||
uint32_t specialTypes;
|
||||
~LocExtKeyData() {
|
||||
if (typeMap != NULL) {
|
||||
uhash_close(typeMap);
|
||||
}
|
||||
}
|
||||
} LocExtKeyData;
|
||||
|
||||
typedef struct LocExtType {
|
||||
|
@ -340,7 +335,7 @@ initFromResourceBundle(UErrorCode& sts) {
|
|||
keyData->bcpId = bcpKeyId;
|
||||
keyData->legacyId = legacyKeyId;
|
||||
keyData->specialTypes = specialTypes;
|
||||
keyData->typeMap = typeDataMap;
|
||||
keyData->typeMap.adoptInstead(typeDataMap);
|
||||
|
||||
uhash_put(gLocExtKeyMap, (void*)legacyKeyId, keyData, &sts);
|
||||
if (legacyKeyId != bcpKeyId) {
|
||||
|
@ -465,7 +460,7 @@ ulocimp_toBcpType(const char* key, const char* type, UBool* isKnownKey, UBool* i
|
|||
if (isKnownKey != NULL) {
|
||||
*isKnownKey = TRUE;
|
||||
}
|
||||
LocExtType* t = (LocExtType*)uhash_get(keyData->typeMap, type);
|
||||
LocExtType* t = (LocExtType*)uhash_get(keyData->typeMap.getAlias(), type);
|
||||
if (t != NULL) {
|
||||
return t->bcpId;
|
||||
}
|
||||
|
@ -510,7 +505,7 @@ ulocimp_toLegacyType(const char* key, const char* type, UBool* isKnownKey, UBool
|
|||
if (isKnownKey != NULL) {
|
||||
*isKnownKey = TRUE;
|
||||
}
|
||||
LocExtType* t = (LocExtType*)uhash_get(keyData->typeMap, type);
|
||||
LocExtType* t = (LocExtType*)uhash_get(keyData->typeMap.getAlias(), type);
|
||||
if (t != NULL) {
|
||||
return t->legacyId;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
#include "unicode/bytestream.h"
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/ures.h"
|
||||
#include "unicode/localpointer.h"
|
||||
#include "unicode/putil.h"
|
||||
#include "unicode/uenum.h"
|
||||
#include "unicode/uloc.h"
|
||||
#include "ustr_imp.h"
|
||||
#include "charstr.h"
|
||||
|
@ -347,6 +349,21 @@ static const char*
|
|||
ultag_getGrandfathered(const ULanguageTag* langtag);
|
||||
#endif
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* \class LocalULanguageTagPointer
|
||||
* "Smart pointer" class, closes a ULanguageTag via ultag_close().
|
||||
* For most methods see the LocalPointerBase base class.
|
||||
*
|
||||
* @see LocalPointerBase
|
||||
* @see LocalPointer
|
||||
* @internal
|
||||
*/
|
||||
U_DEFINE_LOCAL_OPEN_POINTER(LocalULanguageTagPointer, ULanguageTag, ultag_close);
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
/*
|
||||
* -------------------------------------------------
|
||||
*
|
||||
|
@ -1048,14 +1065,12 @@ static void
|
|||
_appendKeywordsToLanguageTag(const char* localeID, icu::ByteSink& sink, UBool strict, UBool hadPosix, UErrorCode* status) {
|
||||
char attrBuf[ULOC_KEYWORD_AND_VALUES_CAPACITY] = { 0 };
|
||||
int32_t attrBufLength = 0;
|
||||
UEnumeration *keywordEnum = NULL;
|
||||
|
||||
keywordEnum = uloc_openKeywords(localeID, status);
|
||||
icu::LocalUEnumerationPointer keywordEnum(uloc_openKeywords(localeID, status));
|
||||
if (U_FAILURE(*status) && !hadPosix) {
|
||||
uenum_close(keywordEnum);
|
||||
return;
|
||||
}
|
||||
if (keywordEnum != NULL || hadPosix) {
|
||||
if (keywordEnum.isValid() || hadPosix) {
|
||||
/* reorder extensions */
|
||||
int32_t len;
|
||||
const char *key;
|
||||
|
@ -1072,7 +1087,7 @@ _appendKeywordsToLanguageTag(const char* localeID, icu::ByteSink& sink, UBool st
|
|||
|
||||
while (TRUE) {
|
||||
icu::CharString buf;
|
||||
key = uenum_next(keywordEnum, NULL, status);
|
||||
key = uenum_next(keywordEnum.getAlias(), NULL, status);
|
||||
if (key == NULL) {
|
||||
break;
|
||||
}
|
||||
|
@ -1334,8 +1349,6 @@ cleanup:
|
|||
attr = tmpAttr;
|
||||
}
|
||||
|
||||
uenum_close(keywordEnum);
|
||||
|
||||
if (U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
|
@ -2561,18 +2574,17 @@ ulocimp_toLanguageTag(const char* localeID,
|
|||
/* For handling special case - private use only tag */
|
||||
pKeywordStart = locale_getKeywordsStart(canonical.data());
|
||||
if (pKeywordStart == canonical.data()) {
|
||||
UEnumeration *kwdEnum;
|
||||
int kwdCnt = 0;
|
||||
UBool done = FALSE;
|
||||
|
||||
kwdEnum = uloc_openKeywords(canonical.data(), &tmpStatus);
|
||||
if (kwdEnum != NULL) {
|
||||
kwdCnt = uenum_count(kwdEnum, &tmpStatus);
|
||||
icu::LocalUEnumerationPointer kwdEnum(uloc_openKeywords(canonical.data(), &tmpStatus));
|
||||
if (U_SUCCESS(tmpStatus)) {
|
||||
kwdCnt = uenum_count(kwdEnum.getAlias(), &tmpStatus);
|
||||
if (kwdCnt == 1) {
|
||||
const char *key;
|
||||
int32_t len = 0;
|
||||
|
||||
key = uenum_next(kwdEnum, &len, &tmpStatus);
|
||||
key = uenum_next(kwdEnum.getAlias(), &len, &tmpStatus);
|
||||
if (len == 1 && *key == PRIVATEUSE) {
|
||||
char buf[ULOC_KEYWORD_AND_VALUES_CAPACITY];
|
||||
buf[0] = PRIVATEUSE;
|
||||
|
@ -2594,7 +2606,6 @@ ulocimp_toLanguageTag(const char* localeID,
|
|||
}
|
||||
}
|
||||
}
|
||||
uenum_close(kwdEnum);
|
||||
if (done) {
|
||||
return;
|
||||
}
|
||||
|
@ -2645,20 +2656,19 @@ ulocimp_forLanguageTag(const char* langtag,
|
|||
icu::ByteSink& sink,
|
||||
int32_t* parsedLength,
|
||||
UErrorCode* status) {
|
||||
ULanguageTag *lt;
|
||||
UBool isEmpty = TRUE;
|
||||
const char *subtag, *p;
|
||||
int32_t len;
|
||||
int32_t i, n;
|
||||
UBool noRegion = TRUE;
|
||||
|
||||
lt = ultag_parse(langtag, tagLen, parsedLength, status);
|
||||
icu::LocalULanguageTagPointer lt(ultag_parse(langtag, tagLen, parsedLength, status));
|
||||
if (U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* language */
|
||||
subtag = ultag_getExtlangSize(lt) > 0 ? ultag_getExtlang(lt, 0) : ultag_getLanguage(lt);
|
||||
subtag = ultag_getExtlangSize(lt.getAlias()) > 0 ? ultag_getExtlang(lt.getAlias(), 0) : ultag_getLanguage(lt.getAlias());
|
||||
if (uprv_compareInvCharsAsAscii(subtag, LANG_UND) != 0) {
|
||||
len = (int32_t)uprv_strlen(subtag);
|
||||
if (len > 0) {
|
||||
|
@ -2668,7 +2678,7 @@ ulocimp_forLanguageTag(const char* langtag,
|
|||
}
|
||||
|
||||
/* script */
|
||||
subtag = ultag_getScript(lt);
|
||||
subtag = ultag_getScript(lt.getAlias());
|
||||
len = (int32_t)uprv_strlen(subtag);
|
||||
if (len > 0) {
|
||||
sink.Append("_", 1);
|
||||
|
@ -2681,7 +2691,7 @@ ulocimp_forLanguageTag(const char* langtag,
|
|||
}
|
||||
|
||||
/* region */
|
||||
subtag = ultag_getRegion(lt);
|
||||
subtag = ultag_getRegion(lt.getAlias());
|
||||
len = (int32_t)uprv_strlen(subtag);
|
||||
if (len > 0) {
|
||||
sink.Append("_", 1);
|
||||
|
@ -2698,7 +2708,7 @@ ulocimp_forLanguageTag(const char* langtag,
|
|||
}
|
||||
|
||||
/* variants */
|
||||
n = ultag_getVariantsSize(lt);
|
||||
n = ultag_getVariantsSize(lt.getAlias());
|
||||
if (n > 0) {
|
||||
if (noRegion) {
|
||||
sink.Append("_", 1);
|
||||
|
@ -2706,7 +2716,7 @@ ulocimp_forLanguageTag(const char* langtag,
|
|||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
subtag = ultag_getVariant(lt, i);
|
||||
subtag = ultag_getVariant(lt.getAlias(), i);
|
||||
sink.Append("_", 1);
|
||||
|
||||
/* write out the variant in upper case */
|
||||
|
@ -2720,15 +2730,13 @@ ulocimp_forLanguageTag(const char* langtag,
|
|||
}
|
||||
|
||||
/* keywords */
|
||||
n = ultag_getExtensionsSize(lt);
|
||||
subtag = ultag_getPrivateUse(lt);
|
||||
n = ultag_getExtensionsSize(lt.getAlias());
|
||||
subtag = ultag_getPrivateUse(lt.getAlias());
|
||||
if (n > 0 || uprv_strlen(subtag) > 0) {
|
||||
if (isEmpty && n > 0) {
|
||||
/* need a language */
|
||||
sink.Append(LANG_UND, LANG_UND_LEN);
|
||||
}
|
||||
_appendKeywords(lt, sink, status);
|
||||
_appendKeywords(lt.getAlias(), sink, status);
|
||||
}
|
||||
|
||||
ultag_close(lt);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue