#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
#include "loccache.h"
#include "uhash.h"
#include "unicode/uloc.h"
#include "umutex.h"
#include "ucln.h"
static UHashtable *gLocaleCache = NULL;
static void U_CALLCONV
hash_freeBundle(void* obj)
{
u_locbund_delete((ULocaleBundle *)obj);
}
ULocaleBundle*
u_loccache_get(const char *loc)
{
ULocaleBundle *result;
UErrorCode status = U_ZERO_ERROR;
if(gLocaleCache == NULL) {
UHashtable *tempCache;
int32_t locCount = uloc_countAvailable();
tempCache = uhash_openSize(uhash_hashChars, uhash_compareChars, locCount, &status);
if(U_FAILURE(status))
return NULL;
uhash_setValueDeleter(tempCache, hash_freeBundle);
umtx_lock(NULL);
if(gLocaleCache == NULL) {
gLocaleCache = tempCache;
}
else {
uhash_close(tempCache);
}
umtx_unlock(NULL);
ucln_ustdio_registerCleanup();
}
result = (ULocaleBundle*)uhash_get(gLocaleCache, loc);
if(result == NULL) {
ULocaleBundle *tempBundle = u_locbund_new(loc);
umtx_lock(NULL);
result = (ULocaleBundle*)uhash_get(gLocaleCache, loc);
if(result == NULL) {
result = tempBundle;
uhash_put(gLocaleCache, tempBundle->fLocale, tempBundle, &status);
}
else {
u_locbund_delete(tempBundle);
}
umtx_unlock(NULL);
}
return result;
}
static UBool loccache_cleanup()
{
if (gLocaleCache) {
uhash_close(gLocaleCache);
gLocaleCache = NULL;
}
return TRUE;
}
static UBool ustdio_cleanup(void)
{
return loccache_cleanup();
}
void ucln_ustdio_registerCleanup()
{
ucln_registerCleanup(UCLN_USTDIO, ustdio_cleanup);
}
#endif