ICU-20249 An internal helper class for stack allocated UResourceBundle.

This commit is contained in:
Fredrik Roubert 2018-10-31 20:18:34 +01:00 committed by Fredrik Roubert
parent 92d0d1447f
commit 710212c495
4 changed files with 80 additions and 24 deletions

View File

@ -125,7 +125,6 @@ static UBool U_CALLCONV uloc_cleanup(void) {
// via the initOnce mechanism.
static void U_CALLCONV loadInstalledLocales() {
UResourceBundle installed;
UErrorCode status = U_ZERO_ERROR;
int32_t i = 0;
int32_t localeCount;
@ -134,22 +133,19 @@ static void U_CALLCONV loadInstalledLocales() {
U_ASSERT(_installedLocalesCount == 0);
_installedLocalesCount = 0;
ures_initStackObject(&installed);
icu::LocalUResourceBundlePointer indexLocale(ures_openDirect(NULL, _kIndexLocaleName, &status));
icu::StackUResourceBundle installed;
// Automatically call ures_close() on this when it goes out of scope.
icu::LocalUResourceBundlePointer installedCloser(&installed);
ures_getByKey(indexLocale.getAlias(), _kIndexTag, &installed, &status);
ures_getByKey(indexLocale.getAlias(), _kIndexTag, installed.getAlias(), &status);
if(U_SUCCESS(status)) {
localeCount = ures_getSize(&installed);
localeCount = ures_getSize(installed.getAlias());
_installedLocales = (char **) uprv_malloc(sizeof(char*) * (localeCount+1));
if (_installedLocales != NULL) {
ures_resetIterator(&installed);
while(ures_hasNext(&installed)) {
ures_getNextString(&installed, NULL, (const char **)&_installedLocales[i++], &status);
ures_resetIterator(installed.getAlias());
while(ures_hasNext(installed.getAlias())) {
ures_getNextString(installed.getAlias(), NULL, (const char **)&_installedLocales[i++], &status);
}
_installedLocales[i] = NULL;
_installedLocalesCount = localeCount;

View File

@ -49,7 +49,6 @@ uloc_getTableStringWithFallback(const char *path, const char *locale,
UErrorCode *pErrorCode)
{
/* char localeBuffer[ULOC_FULLNAME_CAPACITY*4];*/
UResourceBundle table, subTable;
const UChar *item=NULL;
UErrorCode errorCode;
char explicitFallbackName[ULOC_FULLNAME_CAPACITY] = {0};
@ -61,10 +60,6 @@ uloc_getTableStringWithFallback(const char *path, const char *locale,
errorCode=U_ZERO_ERROR;
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 */
*pErrorCode=errorCode;
@ -77,24 +72,24 @@ uloc_getTableStringWithFallback(const char *path, const char *locale,
}
for(;;){
ures_initStackObject(&table);
ures_initStackObject(&subTable);
ures_getByKeyWithFallback(rb.getAlias(), tableKey, &table, &errorCode);
icu::StackUResourceBundle table;
icu::StackUResourceBundle subTable;
ures_getByKeyWithFallback(rb.getAlias(), tableKey, table.getAlias(), &errorCode);
if (subTableKey != NULL) {
/*
ures_getByKeyWithFallback(&table,subTableKey, &subTable, &errorCode);
item = ures_getStringByKeyWithFallback(&subTable, itemKey, pLength, &errorCode);
ures_getByKeyWithFallback(table.getAlias(), subTableKey, subTable.getAlias(), &errorCode);
item = ures_getStringByKeyWithFallback(subTable.getAlias(), itemKey, pLength, &errorCode);
if(U_FAILURE(errorCode)){
*pErrorCode = errorCode;
}
break;*/
ures_getByKeyWithFallback(&table,subTableKey, &table, &errorCode);
ures_getByKeyWithFallback(table.getAlias(), subTableKey, table.getAlias(), &errorCode);
}
if(U_SUCCESS(errorCode)){
item = ures_getStringByKeyWithFallback(&table, itemKey, pLength, &errorCode);
item = ures_getStringByKeyWithFallback(table.getAlias(), itemKey, pLength, &errorCode);
if(U_FAILURE(errorCode)){
const char* replacement = NULL;
*pErrorCode = errorCode; /*save the errorCode*/
@ -107,7 +102,7 @@ uloc_getTableStringWithFallback(const char *path, const char *locale,
}
/*pointer comparison is ok since uloc_getCurrentCountryID & uloc_getCurrentLanguageID return the key itself is replacement is not found*/
if(replacement!=NULL && itemKey != replacement){
item = ures_getStringByKeyWithFallback(&table, replacement, pLength, &errorCode);
item = ures_getStringByKeyWithFallback(table.getAlias(), replacement, pLength, &errorCode);
if(U_SUCCESS(errorCode)){
*pErrorCode = errorCode;
break;
@ -126,7 +121,7 @@ uloc_getTableStringWithFallback(const char *path, const char *locale,
*pErrorCode = errorCode;
errorCode = U_ZERO_ERROR;
fallbackLocale = ures_getStringByKeyWithFallback(&table, "Fallback", &len, &errorCode);
fallbackLocale = ures_getStringByKeyWithFallback(table.getAlias(), "Fallback", &len, &errorCode);
if(U_FAILURE(errorCode)){
*pErrorCode = errorCode;
break;

View File

@ -21,6 +21,7 @@
******************************************************************************
*/
#include "unicode/ures.h"
#include "unicode/ustring.h"
#include "unicode/ucnv.h"
#include "charstr.h"
@ -512,6 +513,18 @@ U_CFUNC void ures_initStackObject(UResourceBundle* resB) {
ures_setIsStackObject(resB, TRUE);
}
U_NAMESPACE_BEGIN
StackUResourceBundle::StackUResourceBundle() {
ures_initStackObject(&bundle);
}
StackUResourceBundle::~StackUResourceBundle() {
ures_close(&bundle);
}
U_NAMESPACE_END
static UBool // returns U_SUCCESS(*status)
loadParentsExceptRoot(UResourceDataEntry *&t1,
char name[], int32_t nameCapacity,

View File

@ -11,6 +11,7 @@
#define URESIMP_H
#include "unicode/ures.h"
#include "unicode/utypes.h"
#include "uresdata.h"
@ -82,6 +83,57 @@ struct UResourceBundle {
U_CAPI void U_EXPORT2 ures_initStackObject(UResourceBundle* resB);
#ifdef __cplusplus
U_NAMESPACE_BEGIN
/**
* \class StackUResourceBundle
* "Smart pointer" like class, closes a UResourceBundle via ures_close().
*
* This code:
*
* StackUResourceBundle bundle;
* foo(bundle.getAlias());
*
* Is equivalent to this code:
*
* UResourceBundle bundle;
* ures_initStackObject(&bundle);
* foo(&bundle);
* ures_close(&bundle);
*
* @see LocalUResourceBundlePointer
* @internal
*/
class StackUResourceBundle {
public:
StackUResourceBundle();
~StackUResourceBundle();
UResourceBundle* getAlias() { return &bundle; }
StackUResourceBundle(const StackUResourceBundle&) = delete;
StackUResourceBundle& operator=(const StackUResourceBundle&) = delete;
StackUResourceBundle(StackUResourceBundle&&) = delete;
StackUResourceBundle& operator=(StackUResourceBundle&&) = delete;
private:
UResourceBundle bundle;
// No heap allocation. Use only on the stack.
static void* U_EXPORT2 operator new(size_t);
static void* U_EXPORT2 operator new[](size_t);
#if U_HAVE_PLACEMENT_NEW
static void* U_EXPORT2 operator new(size_t, void*);
#endif
};
U_NAMESPACE_END
#endif /* __cplusplus */
/**
* Opens a resource bundle for the locale;
* if there is not even a base language bundle, then loads the root bundle;