7e92471c93
X-SVN-Rev: 9295
118 lines
3.0 KiB
C
118 lines
3.0 KiB
C
/*
|
|
*******************************************************************************
|
|
*
|
|
* Copyright (C) 1998-2002, International Business Machines
|
|
* Corporation and others. All Rights Reserved.
|
|
*
|
|
*******************************************************************************
|
|
*
|
|
* File loccache.c
|
|
*
|
|
* Modification History:
|
|
*
|
|
* Date Name Description
|
|
* 11/18/98 stephen Creation.
|
|
* 03/11/99 stephen Modified for new C API.
|
|
* 06/16/99 stephen Added #include for uloc.h
|
|
*******************************************************************************
|
|
*/
|
|
|
|
#include "loccache.h"
|
|
#include "uhash.h"
|
|
#include "unicode/uloc.h"
|
|
#include "umutex.h"
|
|
#include "ucln.h"
|
|
|
|
/* The global cache */
|
|
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;
|
|
|
|
/* Create the cache, if needed */
|
|
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);
|
|
|
|
/* Lock the cache */
|
|
umtx_lock(NULL);
|
|
/* Make sure it didn't change while we were acquiring the lock */
|
|
if(gLocaleCache == NULL) {
|
|
gLocaleCache = tempCache;
|
|
}
|
|
else {
|
|
uhash_close(tempCache);
|
|
}
|
|
|
|
/* Unlock the cache */
|
|
umtx_unlock(NULL);
|
|
ucln_ustdio_registerCleanup();
|
|
}
|
|
|
|
/* Try and get the bundle from the cache */
|
|
/* This will be slightly wasteful the first time around, */
|
|
/* since we know the cache will be empty. But, it simplifies */
|
|
/* the code a great deal. */
|
|
|
|
result = (ULocaleBundle*)uhash_get(gLocaleCache, loc);
|
|
|
|
/* If the bundle wasn't found, create it and add it to the cache */
|
|
if(result == NULL) {
|
|
/* Create the bundle */
|
|
ULocaleBundle *tempBundle = u_locbund_new(loc);
|
|
|
|
/* Lock the cache */
|
|
umtx_lock(NULL);
|
|
|
|
/* Make sure the cache didn't change while we were locking it */
|
|
result = (ULocaleBundle*)uhash_get(gLocaleCache, loc);
|
|
if(result == NULL) {
|
|
result = tempBundle;
|
|
uhash_put(gLocaleCache, tempBundle->fLocale, tempBundle, &status);
|
|
}
|
|
else {
|
|
u_locbund_delete(tempBundle);
|
|
}
|
|
|
|
/* Unlock the cache */
|
|
umtx_unlock(NULL);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static UBool loccache_cleanup()
|
|
{
|
|
if (gLocaleCache) {
|
|
uhash_close(gLocaleCache);
|
|
gLocaleCache = NULL;
|
|
}
|
|
return TRUE; /* Everything was cleaned up */
|
|
}
|
|
|
|
static UBool ustdio_cleanup(void)
|
|
{
|
|
return loccache_cleanup();
|
|
}
|
|
|
|
void ucln_ustdio_registerCleanup()
|
|
{
|
|
ucln_registerCleanup(UCLN_USTDIO, ustdio_cleanup);
|
|
}
|
|
|