summaryrefslogtreecommitdiff
path: root/i18npool
diff options
context:
space:
mode:
authorIvo Hinkelmann <ihi@openoffice.org>2008-01-14 12:54:41 +0000
committerIvo Hinkelmann <ihi@openoffice.org>2008-01-14 12:54:41 +0000
commitaf0b586ec6c4d6041f8af6eb8c4743ba7b36e775 (patch)
tree4ad55b3e321760ff2b6486d50b6e08235f827c94 /i18npool
parented3d6066cad854012127c272aab991727aac510c (diff)
INTEGRATION: CWS chart15 (1.53.4); FILE MERGED
2007/12/14 13:00:43 bm 1.53.4.9: #i84276# commented-out code removed 2007/12/14 12:47:38 bm 1.53.4.8: #i84276# additional check, hark! 2007/12/14 12:46:00 bm 1.53.4.7: #i84276# additional check 2007/12/14 11:43:32 bm 1.53.4.6: #i84276# make cachedItem a member of the LocaleData class again 2007/12/14 10:53:09 bm 1.53.4.5: #i84276# use more safe singleton implementation 2007/12/12 09:52:56 bm 1.53.4.4: RESYNC: (1.53-1.54); FILE MERGED 2007/12/06 17:10:15 iha 1.53.4.3: #i84276# avoid repeated loading and unloading of localedata lib 2007/12/05 19:35:44 iha 1.53.4.2: #i84276# avoid repeated loading and unloading of localedata lib - reorganize for solaris compiler 2007/12/05 18:03:14 iha 1.53.4.1: #i84276# avoid repeated loading and unloading of localedata lib
Diffstat (limited to 'i18npool')
-rw-r--r--i18npool/source/localedata/localedata.cxx256
1 files changed, 175 insertions, 81 deletions
diff --git a/i18npool/source/localedata/localedata.cxx b/i18npool/source/localedata/localedata.cxx
index b57886ec5dbb..e7d78fd683b8 100644
--- a/i18npool/source/localedata/localedata.cxx
+++ b/i18npool/source/localedata/localedata.cxx
@@ -4,9 +4,9 @@
*
* $RCSfile: localedata.cxx,v $
*
- * $Revision: 1.54 $
+ * $Revision: 1.55 $
*
- * last change: $Author: rt $ $Date: 2007-11-13 14:33:45 $
+ * last change: $Author: ihi $ $Date: 2008-01-14 13:54:41 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
@@ -44,6 +44,7 @@
#endif
#include <string.h>
#include <stdio.h>
+#include "rtl/instance.hxx"
#if OSL_DEBUG_LEVEL == 0
# ifndef NDEBUG
@@ -257,14 +258,27 @@ static const sal_Unicode under = sal_Unicode('_');
static const sal_Int16 nbOfLocales = sizeof(aLibTable) / sizeof(aLibTable[0]);
-LocaleData::~LocaleData()
+struct LocaleDataLookupTableItem
{
- for (size_t l = 0; l < lookupTable.size(); l++) {
- cachedItem = lookupTable[l];
- delete cachedItem->module;
- delete cachedItem;
+ LocaleDataLookupTableItem(const sal_Char *name, osl::Module* m, const sal_Char* lname) : dllName(name), module(m), localeName(lname)
+ {
+ }
+ const sal_Char* dllName;
+ osl::Module *module;
+ const sal_Char* localeName;
+
+ com::sun::star::lang::Locale aLocale;
+ sal_Bool equals(const com::sun::star::lang::Locale& rLocale)
+ {
+ return (rLocale == aLocale);
}
- lookupTable.clear();
+};
+
+LocaleData::LocaleData()
+{
+}
+LocaleData::~LocaleData()
+{
}
@@ -307,6 +321,137 @@ LocaleData::getLocaleItem( const Locale& rLocale ) throw(RuntimeException)
}
}
+extern "C" { static void SAL_CALL thisModule() {} }
+
+namespace
+{
+
+// implement the lookup table as a safe static object
+class lcl_LookupTableHelper
+{
+public:
+ lcl_LookupTableHelper();
+ ~lcl_LookupTableHelper();
+
+ oslGenericFunction SAL_CALL getFunctionSymbolByName(
+ const OUString& localeName, const sal_Char* pFunction,
+ LocaleDataLookupTableItem** pOutCachedItem );
+
+private:
+ ::osl::Mutex maMutex;
+ ::std::vector< LocaleDataLookupTableItem* > maLookupTable;
+};
+
+// from instance.hxx: Helper base class for a late-initialized
+// (default-constructed) static variable, implementing the double-checked
+// locking pattern correctly.
+// usage: lcl_LookupTableHelper & rLookupTable = lcl_LookupTableStatic::get();
+// retrieves the singleton lookup table instance
+struct lcl_LookupTableStatic : public ::rtl::Static< lcl_LookupTableHelper, lcl_LookupTableStatic >
+{};
+
+lcl_LookupTableHelper::lcl_LookupTableHelper()
+{
+}
+
+lcl_LookupTableHelper::~lcl_LookupTableHelper()
+{
+ LocaleDataLookupTableItem* pItem = 0;
+
+ std::vector<LocaleDataLookupTableItem*>::const_iterator aEnd(maLookupTable.end());
+ std::vector<LocaleDataLookupTableItem*>::iterator aIter(maLookupTable.begin());
+
+ for ( ; aIter != aEnd; ++aIter ) {
+ pItem = *aIter;
+ delete pItem->module;
+ delete pItem;
+ }
+ maLookupTable.clear();
+}
+
+oslGenericFunction SAL_CALL lcl_LookupTableHelper::getFunctionSymbolByName(
+ const OUString& localeName, const sal_Char* pFunction,
+ LocaleDataLookupTableItem** pOutCachedItem )
+{
+ OUString aFallback;
+ bool bFallback = (localeName.indexOf( under) < 0);
+ if (bFallback)
+ {
+ Locale aLocale;
+ aLocale.Language = localeName;
+ Locale aFbLocale = MsLangId::getFallbackLocale( aLocale);
+ if (aFbLocale == aLocale)
+ bFallback = false; // may be a "language-only-locale" like Interlingua (ia)
+ else if (aFbLocale.Country.getLength()) {
+ OUStringBuffer aBuf(5);
+ aFallback = aBuf.append(aFbLocale.Language).append( under).append(aFbLocale.Country).makeStringAndClear();
+ }
+ else
+ aFallback = aFbLocale.Language;
+ }
+
+ for ( sal_Int16 i = 0; i < nbOfLocales; i++)
+ {
+ if (localeName.equalsAscii(aLibTable[i].pLocale) ||
+ (bFallback && localeName == aFallback))
+ {
+ LocaleDataLookupTableItem* pCurrent = 0;
+ OUStringBuffer aBuf(strlen(aLibTable[i].pLocale) + 1 + strlen(pFunction));
+ {
+ ::osl::MutexGuard aGuard( maMutex );
+ for (size_t l = 0; l < maLookupTable.size(); l++)
+ {
+ pCurrent = maLookupTable[l];
+ if (pCurrent->dllName == aLibTable[i].pLib)
+ {
+ OSL_ASSERT( pOutCachedItem );
+ if( pOutCachedItem )
+ {
+ (*pOutCachedItem) = new LocaleDataLookupTableItem( *pCurrent );
+ (*pOutCachedItem)->localeName = aLibTable[i].pLocale;
+ return (*pOutCachedItem)->module->getFunctionSymbol(
+ aBuf.appendAscii( pFunction).append( under).
+ appendAscii( (*pOutCachedItem)->localeName).makeStringAndClear());
+ }
+ else
+ return NULL;
+ }
+ }
+ }
+ // Library not loaded, load it and add it to the list.
+#ifdef SAL_DLLPREFIX
+ aBuf.ensureCapacity(strlen(aLibTable[i].pLib) + 6); // mostly "lib*.so"
+ aBuf.appendAscii( SAL_DLLPREFIX ).appendAscii(aLibTable[i].pLib).appendAscii( SAL_DLLEXTENSION );
+#else
+ aBuf.ensureCapacity(strlen(aLibTable[i].pLib) + 4); // mostly "*.dll"
+ aBuf.appendAscii(aLibTable[i].pLib).appendAscii( SAL_DLLEXTENSION );
+#endif
+ osl::Module *module = new osl::Module();
+ if ( module->loadRelative(&thisModule, aBuf.makeStringAndClear()) )
+ {
+ ::osl::MutexGuard aGuard( maMutex );
+ LocaleDataLookupTableItem* pNewItem = 0;
+ maLookupTable.push_back(pNewItem = new LocaleDataLookupTableItem(aLibTable[i].pLib, module, aLibTable[i].pLocale ));
+ OSL_ASSERT( pOutCachedItem );
+ if( pOutCachedItem )
+ {
+ (*pOutCachedItem) = new LocaleDataLookupTableItem( *pNewItem );
+ return module->getFunctionSymbol(
+ aBuf.appendAscii(pFunction).append(under).
+ appendAscii((*pOutCachedItem)->localeName).makeStringAndClear());
+ }
+ else
+ return NULL;
+ }
+ else
+ delete module;
+ }
+ }
+ return NULL;
+}
+
+} // anonymous namespace
+
#define REF_DAYS 0
#define REF_MONTHS 1
#define REF_ERAS 2
@@ -1113,8 +1258,10 @@ LocaleData::getOutlineNumberingLevels( const lang::Locale& rLocale ) throw(Runti
oslGenericFunction SAL_CALL LocaleData::getFunctionSymbol( const Locale& rLocale, const sal_Char* pFunction )
throw(RuntimeException)
{
+ lcl_LookupTableHelper & rLookupTable = lcl_LookupTableStatic::get();
+
OUStringBuffer aBuf(1);
- if (cachedItem && cachedItem->equals(rLocale)) {
+ if (cachedItem.get() && cachedItem->equals(rLocale)) {
aBuf.ensureCapacity(strlen(pFunction) + 1 + strlen(cachedItem->localeName));
return cachedItem->module->getFunctionSymbol(aBuf.appendAscii(pFunction).append(under).
appendAscii(cachedItem->localeName).makeStringAndClear());
@@ -1129,93 +1276,37 @@ oslGenericFunction SAL_CALL LocaleData::getFunctionSymbol( const Locale& rLocale
sal_Int32 v = rLocale.Variant.getLength();
aBuf.ensureCapacity(l+c+v+3);
+ LocaleDataLookupTableItem *pCachedItem = 0;
+
if ((l > 0 && c > 0 && v > 0 &&
// load function with name <func>_<lang>_<country>_<varian>
- (pSymbol = getFunctionSymbolByName(aBuf.append(rLocale.Language).append(under).append(
- rLocale.Country).append(under).append(rLocale.Variant).makeStringAndClear(), pFunction)) != 0) ||
+ (pSymbol = rLookupTable.getFunctionSymbolByName(aBuf.append(rLocale.Language).append(under).append(
+ rLocale.Country).append(under).append(rLocale.Variant).makeStringAndClear(), pFunction, &pCachedItem)) != 0) ||
(l > 0 && c > 0 &&
// load function with name <ase>_<lang>_<country>
- (pSymbol = getFunctionSymbolByName(aBuf.append(rLocale.Language).append(under).append(
- rLocale.Country).makeStringAndClear(), pFunction)) != 0) ||
+ (pSymbol = rLookupTable.getFunctionSymbolByName(aBuf.append(rLocale.Language).append(under).append(
+ rLocale.Country).makeStringAndClear(), pFunction, &pCachedItem)) != 0) ||
(l > 0 && c > 0 && rLocale.Language.equalsAscii("zh") &&
(rLocale.Country.equalsAscii("HK") ||
rLocale.Country.equalsAscii("MO")) &&
// if the country code is HK or MO, one more step to try TW.
- (pSymbol = getFunctionSymbolByName(aBuf.append(rLocale.Language).append(under).append(tw).makeStringAndClear(),
- pFunction)) != 0) ||
+ (pSymbol = rLookupTable.getFunctionSymbolByName(aBuf.append(rLocale.Language).append(under).append(tw).makeStringAndClear(),
+ pFunction, &pCachedItem)) != 0) ||
(l > 0 &&
// load function with name <func>_<lang>
- (pSymbol = getFunctionSymbolByName(rLocale.Language, pFunction)) != 0) ||
+ (pSymbol = rLookupTable.getFunctionSymbolByName(rLocale.Language, pFunction, &pCachedItem)) != 0) ||
// load default function with name <func>_en_US
- (pSymbol = getFunctionSymbolByName(en_US, pFunction)) != 0) {
- cachedItem->aLocale = rLocale;
+ (pSymbol = rLookupTable.getFunctionSymbolByName(en_US, pFunction, &pCachedItem)) != 0)
+ {
+ if( pCachedItem )
+ cachedItem.reset( pCachedItem );
+ if( cachedItem.get())
+ cachedItem->aLocale = rLocale;
return pSymbol;
}
throw RuntimeException();
}
-extern "C" { static void SAL_CALL thisModule() {} }
-
-oslGenericFunction SAL_CALL LocaleData::getFunctionSymbolByName( const OUString& localeName, const sal_Char* pFunction )
-{
- OUString aFallback;
- bool bFallback = (localeName.indexOf( under) < 0);
- if (bFallback)
- {
- Locale aLocale;
- aLocale.Language = localeName;
- Locale aFbLocale = MsLangId::getFallbackLocale( aLocale);
- if (aFbLocale == aLocale)
- bFallback = false; // may be a "language-only-locale" like Interlingua (ia)
- else if (aFbLocale.Country.getLength()) {
- OUStringBuffer aBuf(5);
- aFallback = aBuf.append(aFbLocale.Language).append( under).append(aFbLocale.Country).makeStringAndClear();
- }
- else
- aFallback = aFbLocale.Language;
- }
-
- for ( sal_Int16 i = 0; i < nbOfLocales; i++)
- {
- if (localeName.equalsAscii(aLibTable[i].pLocale) ||
- (bFallback && localeName == aFallback))
- {
- OUStringBuffer aBuf(strlen(aLibTable[i].pLocale) + 1 + strlen(pFunction));
- for (size_t l = 0; l < lookupTable.size(); l++)
- {
- cachedItem = lookupTable[l];
- if (cachedItem->dllName == aLibTable[i].pLib)
- {
- cachedItem->localeName = aLibTable[i].pLocale;
- return cachedItem->module->getFunctionSymbol(
- aBuf.appendAscii( pFunction).append( under).
- appendAscii( cachedItem->localeName).makeStringAndClear());
- }
- }
- // Library not loaded, load it and add it to the list.
-#ifdef SAL_DLLPREFIX
- aBuf.ensureCapacity(strlen(aLibTable[i].pLib) + 6); // mostly "lib*.so"
- aBuf.appendAscii( SAL_DLLPREFIX ).appendAscii(aLibTable[i].pLib).appendAscii( SAL_DLLEXTENSION );
-#else
- aBuf.ensureCapacity(strlen(aLibTable[i].pLib) + 4); // mostly "*.dll"
- aBuf.appendAscii(aLibTable[i].pLib).appendAscii( SAL_DLLEXTENSION );
-#endif
- osl::Module *module = new osl::Module();
- if ( module->loadRelative(&thisModule, aBuf.makeStringAndClear()) )
- {
- lookupTable.push_back(cachedItem = new lookupTableItem(aLibTable[i].pLib, module));
- cachedItem->localeName = aLibTable[i].pLocale;
- return module->getFunctionSymbol(
- aBuf.appendAscii(pFunction).append(under).
- appendAscii(cachedItem->localeName).makeStringAndClear());
- }
- else
- delete module;
- }
- }
- return NULL;
-}
-
Sequence< Locale > SAL_CALL
LocaleData::getAllInstalledLocaleNames() throw(RuntimeException)
{
@@ -1228,7 +1319,10 @@ LocaleData::getAllInstalledLocaleNames() throw(RuntimeException)
// Check if the locale is really available and not just in the table,
// don't allow fall backs.
- if (getFunctionSymbolByName( name, "getLocaleItem" )) {
+ LocaleDataLookupTableItem *pCachedItem = 0;
+ if (lcl_LookupTableStatic::get().getFunctionSymbolByName( name, "getLocaleItem", &pCachedItem )) {
+ if( pCachedItem )
+ cachedItem.reset( pCachedItem );
sal_Int32 index = 0;
lang::Locale tmpLocale(name.getToken(0, under, index), empStr, empStr);
if (index >= 0) {