summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolan.mcnamara@collabora.com>2024-03-28 09:55:06 +0000
committerCaolán McNamara <caolan.mcnamara@collabora.com>2024-03-29 09:51:12 +0100
commite8e0a3b1d7e706330ca343cf9dd5ba062e9ff0c4 (patch)
tree544402e3766feec77b0a717b45a43946da8f9ff2
parent40176bd39c94c32ac0269d9994e8e50518d84467 (diff)
crashtesting: fix SvNFEngine::CacheFormatRO assert
since: commit c6c6126aa3e8de256091b829b98b5943db6a8be6 Author: Caolán McNamara <caolan.mcnamara@collabora.com> Date: Thu Mar 21 17:25:35 2024 +0000 Related: tdf#160056 refactor SvNumberFormatter to split it into two constituent parts Change-Id: I4add9f383789ab03ceab751b07973448a41911ba Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165490 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
-rw-r--r--include/svl/nfengine.hxx28
-rw-r--r--include/svl/numformat.hxx2
-rw-r--r--sc/inc/interpretercontext.hxx7
-rw-r--r--sc/source/core/data/document.cxx1
-rw-r--r--sc/source/core/tool/interpretercontext.cxx15
-rw-r--r--svl/source/numbers/zforlist.cxx162
6 files changed, 148 insertions, 67 deletions
diff --git a/include/svl/nfengine.hxx b/include/svl/nfengine.hxx
index a4890e074d1a..c0b463c189f3 100644
--- a/include/svl/nfengine.hxx
+++ b/include/svl/nfengine.hxx
@@ -159,10 +159,12 @@ private:
class SVL_DLLPUBLIC SvNFFormatData
{
+public:
+ typedef std::map<sal_uInt32, sal_uInt32> DefaultFormatKeysMap;
+
private:
typedef std::map<sal_uInt32, std::unique_ptr<SvNumberformat>> FormatEntryMap;
FormatEntryMap aFTable; // Table of format keys to format entries
- typedef std::map<sal_uInt32, sal_uInt32> DefaultFormatKeysMap;
DefaultFormatKeysMap aDefaultFormatKeys; // Table of default standard to format keys
sal_uInt32 MaxCLOffset; // Max language/country offset used
sal_uInt32 nDefaultSystemCurrencyFormat; // NewCurrency matching SYSTEM locale
@@ -190,6 +192,8 @@ public:
bool GetNewCurrencySymbolString(sal_uInt32 nFormat, OUString& rSymbol,
const NfCurrencyEntry** ppEntry, bool* pBank = nullptr) const;
+ void MergeDefaultFormatKeys(const DefaultFormatKeysMap& rDefaultFormatKeys);
+
private:
SvNFFormatData(const SvNFFormatData&) = delete;
SvNFFormatData& operator=(const SvNFFormatData&) = delete;
@@ -262,8 +266,7 @@ private:
SVL_DLLPRIVATE sal_uInt32 ImpGetDefaultSystemCurrencyFormat(SvNFLanguageData& rCurrentLanguage,
const NativeNumberWrapper* pNatNum);
- SVL_DLLPRIVATE std::pair<sal_uInt32, bool>
- ImpGetDefaultFormat(SvNumFormatType nType, sal_uInt32 nSearch, sal_uInt32 CLOffset) const;
+ SVL_DLLPRIVATE sal_uInt32 FindCachedDefaultFormat(sal_uInt32 nSearch) const;
SVL_DLLPRIVATE static sal_Int32
ImpGetFormatCodeIndex(const SvNFLanguageData& rCurrentLanguage,
@@ -282,6 +285,7 @@ public:
const NativeNumberWrapper* pNatNum, LanguageType eLnge)>
GetCLOffset;
typedef std::function<void(sal_uInt32 nSearch, sal_uInt32 nFormat)> CacheFormat;
+ typedef std::function<sal_uInt32(sal_uInt32 nSearch)> FindFormat;
typedef std::function<sal_uInt32(SvNFLanguageData& rCurrentLanguage,
const NativeNumberWrapper* pNatNum, sal_uInt32 CLOffset,
@@ -292,11 +296,13 @@ public:
{
GetCLOffset mGetCLOffset;
CacheFormat mCacheFormat;
+ FindFormat mFindFormat;
GetDefaultCurrency mGetDefaultCurrency;
};
static Accessor GetRWPolicy(SvNFFormatData& rFormatData);
- static Accessor GetROPolicy(const SvNFFormatData& rFormatData);
+ static Accessor GetROPolicy(const SvNFFormatData& rFormatData,
+ SvNFFormatData::DefaultFormatKeysMap& rFormatCache);
static void ChangeIntl(SvNFLanguageData& rCurrentLanguage, LanguageType eLnge);
static void ChangeNullDate(SvNFLanguageData& rCurrentLanguage, sal_uInt16 nDay,
@@ -403,9 +409,12 @@ public:
bool IsRed, sal_uInt16 nPrecision, sal_uInt16 nLeadingZeros);
private:
- static sal_uInt32 ImpGetDefaultFormat(const SvNFFormatData& rFormatData,
- const SvNFEngine::CacheFormat& rFunc,
+ static sal_uInt32 ImpGetDefaultFormat(const SvNFFormatData& rFormatData, const Accessor& rFuncs,
SvNumFormatType nType, sal_uInt32 CLOffset);
+
+ static sal_uInt32 ImpGetDefaultFormat(const SvNFFormatData& rFormatData, SvNumFormatType nType,
+ sal_uInt32 CLOffset);
+
static sal_uInt32
ImpGetStandardFormat(SvNFLanguageData& rCurrentLanguage, const SvNFFormatData& rFormatData,
const NativeNumberWrapper* pNatNum, const SvNFEngine::Accessor& rFuncs,
@@ -425,8 +434,13 @@ private:
const NativeNumberWrapper*, LanguageType eLnge);
static void CacheFormatRW(SvNFFormatData& rFormatData, sal_uInt32 nSearch, sal_uInt32 nFormat);
- static void CacheFormatRO(const SvNFFormatData& rFormatData, sal_uInt32 nSearch,
+ static void CacheFormatRO(SvNFFormatData::DefaultFormatKeysMap& rMap, sal_uInt32 nSearch,
sal_uInt32 nFormat);
+
+ static sal_uInt32 FindFormatRW(const SvNFFormatData& rFormatData, sal_uInt32 nSearch);
+ static sal_uInt32 FindFormatRO(const SvNFFormatData& rFormatData,
+ const SvNFFormatData::DefaultFormatKeysMap& rMap,
+ sal_uInt32 nSearch);
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/svl/numformat.hxx b/include/svl/numformat.hxx
index b26e245ca8d5..92f93bb1562a 100644
--- a/include/svl/numformat.hxx
+++ b/include/svl/numformat.hxx
@@ -507,6 +507,8 @@ public:
language/country, used in XML import */
OUString GetStandardName(LanguageType eLnge);
+ void MergeDefaultFormatKeys(const SvNFFormatData::DefaultFormatKeysMap& rDefaultFormatKeys);
+
/** Check if a specific locale has supported locale data. */
static bool IsLocaleInstalled(LanguageType eLang);
diff --git a/sc/inc/interpretercontext.hxx b/sc/inc/interpretercontext.hxx
index 2f89249a21a6..ead9b04c06c7 100644
--- a/sc/inc/interpretercontext.hxx
+++ b/sc/inc/interpretercontext.hxx
@@ -112,6 +112,8 @@ struct ScInterpreterContext
OUString NFGetCalcCellReturn(sal_uInt32 nFormat) const;
+ void MergeDefaultFormatKeys(SvNumberFormatter& rFormatter) const;
+
private:
friend class ScInterpreterContextPool;
void ResetTokens();
@@ -125,6 +127,11 @@ private:
// the NumberFormat's data and a throw-away object for currently used language
// This is essentially an exploded view of mpFormatter
std::unique_ptr<SvNFLanguageData> mxLanguageData;
+ // FormatData can be driven read-only, but may want to cache some data,
+ // in RO Mode we can cache per thread to mxAuxFormatKeyMap, and
+ // discard or merge after threaded calculation is over
+ std::unique_ptr<SvNFFormatData::DefaultFormatKeysMap> mxAuxFormatKeyMap;
+
const SvNFFormatData* mpFormatData;
SvNFEngine::Accessor maROPolicy;
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 04370b62117f..e87d100b36da 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6929,6 +6929,7 @@ void ScDocument::MergeContextBackIntoNonThreadedContext(ScInterpreterContext& th
std::make_move_iterator(threadedContext.maDelayedSetNumberFormat.begin()),
std::make_move_iterator(threadedContext.maDelayedSetNumberFormat.end()));
// lookup cache is now only in pooled ScInterpreterContext's
+ threadedContext.MergeDefaultFormatKeys(*GetFormatTable());
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/interpretercontext.cxx b/sc/source/core/tool/interpretercontext.cxx
index f4fde3725414..e1fc5fb24252 100644
--- a/sc/source/core/tool/interpretercontext.cxx
+++ b/sc/source/core/tool/interpretercontext.cxx
@@ -46,8 +46,9 @@ ScInterpreterContext::ScInterpreterContext(const ScDocument& rDoc, SvNumberForma
else
{
mxLanguageData.reset(new SvNFLanguageData(pFormatter->GetROLanguageData()));
+ mxAuxFormatKeyMap.reset(new SvNFFormatData::DefaultFormatKeysMap);
mpFormatData = &pFormatter->GetROFormatData();
- maROPolicy = SvNFEngine::GetROPolicy(*mpFormatData);
+ maROPolicy = SvNFEngine::GetROPolicy(*mpFormatData, *mxAuxFormatKeyMap);
}
}
@@ -74,8 +75,9 @@ void ScInterpreterContext::SetDocAndFormatter(const ScDocument& rDoc, SvNumberFo
{
// formatter has changed
mxLanguageData.reset(new SvNFLanguageData(pFormatter->GetROLanguageData()));
+ mxAuxFormatKeyMap.reset(new SvNFFormatData::DefaultFormatKeysMap);
mpFormatData = &pFormatter->GetROFormatData();
- maROPolicy = SvNFEngine::GetROPolicy(*mpFormatData);
+ maROPolicy = SvNFEngine::GetROPolicy(*mpFormatData, *mxAuxFormatKeyMap);
mpFormatter = pFormatter;
// drop cache
@@ -88,8 +90,14 @@ void ScInterpreterContext::initFormatTable()
{
mpFormatter = mpDoc->GetFormatTable(); // will assert if not main thread
mpFormatData = &mpFormatter->GetROFormatData();
- maROPolicy = SvNFEngine::GetROPolicy(*mpFormatData);
mxLanguageData.reset(new SvNFLanguageData(mpFormatter->GetROLanguageData()));
+ mxAuxFormatKeyMap.reset(new SvNFFormatData::DefaultFormatKeysMap);
+ maROPolicy = SvNFEngine::GetROPolicy(*mpFormatData, *mxAuxFormatKeyMap);
+}
+
+void ScInterpreterContext::MergeDefaultFormatKeys(SvNumberFormatter& rFormatter) const
+{
+ rFormatter.MergeDefaultFormatKeys(*mxAuxFormatKeyMap);
}
void ScInterpreterContext::Cleanup()
@@ -106,6 +114,7 @@ void ScInterpreterContext::ClearLookupCache(const ScDocument* pDoc)
{
mxScLookupCache.reset();
mxLanguageData.reset();
+ mxAuxFormatKeyMap.reset();
mpFormatter = nullptr;
mpFormatData = nullptr;
}
diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx
index 9a4490849d11..7b2bcd4352e7 100644
--- a/svl/source/numbers/zforlist.cxx
+++ b/svl/source/numbers/zforlist.cxx
@@ -1537,17 +1537,19 @@ static sal_uInt32 ImpGetSearchOffset(SvNumFormatType nType, sal_uInt32 CLOffset)
return nSearch;
}
+// static
sal_uInt32 SvNFEngine::ImpGetDefaultFormat(const SvNFFormatData& rFormatData,
- const SvNFEngine::CacheFormat& rFunc,
+ const SvNFEngine::Accessor& rFuncs,
SvNumFormatType nType, sal_uInt32 CLOffset)
{
sal_uInt32 nSearch = ImpGetSearchOffset(nType, CLOffset);
- std::pair<sal_uInt32, bool> aRes = rFormatData.ImpGetDefaultFormat(nType, nSearch, CLOffset);
- const sal_uInt32 nDefaultFormat = aRes.first;
- const bool bShouldCache = aRes.second;
- if (bShouldCache)
- rFunc(nSearch, nDefaultFormat);
+ sal_uInt32 nDefaultFormat = rFuncs.mFindFormat(nSearch);
+ if (nDefaultFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
+ return nDefaultFormat;
+
+ nDefaultFormat = ImpGetDefaultFormat(rFormatData, nType, CLOffset);
+ rFuncs.mCacheFormat(nSearch, nDefaultFormat);
return nDefaultFormat;
}
@@ -1602,7 +1604,7 @@ sal_uInt32 SvNFEngine::ImpGetStandardFormat(SvNFLanguageData& rCurrentLanguage,
case SvNumFormatType::DATETIME:
case SvNumFormatType::PERCENT:
case SvNumFormatType::SCIENTIFIC:
- return ImpGetDefaultFormat(rFormatData, rFuncs.mCacheFormat, eType, CLOffset);
+ return ImpGetDefaultFormat(rFormatData, rFuncs, eType, CLOffset);
case SvNumFormatType::FRACTION:
return CLOffset + ZF_STANDARD_FRACTION;
case SvNumFormatType::LOGICAL:
@@ -1669,59 +1671,70 @@ sal_uInt32 SvNFEngine::GetStandardFormat(SvNFLanguageData& rCurrentLanguage,
return ImpGetStandardFormat(rCurrentLanguage, rFormatData, pNatNum, rFuncs, eType, nCLOffset, eLnge);
}
-//return a std::pair with the result and true/false if that result should be cached in aDefaultFormatKeys
-std::pair<sal_uInt32, bool> SvNFFormatData::ImpGetDefaultFormat(SvNumFormatType nType, sal_uInt32 nSearch, sal_uInt32 CLOffset) const
+namespace
{
- bool bShouldCache = false;
- DefaultFormatKeysMap::const_iterator it = aDefaultFormatKeys.find(nSearch);
- sal_uInt32 nDefaultFormat = (it != aDefaultFormatKeys.end() ?
- it->second : NUMBERFORMAT_ENTRY_NOT_FOUND);
- if ( nDefaultFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
+ sal_uInt32 FindCachedDefaultFormat(const SvNFFormatData::DefaultFormatKeysMap& rDefaultFormatKeys, sal_uInt32 nSearch)
{
- // look for a defined standard
- sal_uInt32 nStopKey = CLOffset + SV_COUNTRY_LANGUAGE_OFFSET;
- sal_uInt32 nKey(0);
- auto it2 = aFTable.find( CLOffset );
- while ( it2 != aFTable.end() && (nKey = it2->first ) >= CLOffset && nKey < nStopKey )
+ auto it = rDefaultFormatKeys.find(nSearch);
+ sal_uInt32 nDefaultFormat = (it != rDefaultFormatKeys.end() ?
+ it->second : NUMBERFORMAT_ENTRY_NOT_FOUND);
+ return nDefaultFormat;
+ }
+}
+
+sal_uInt32 SvNFFormatData::FindCachedDefaultFormat(sal_uInt32 nSearch) const
+{
+ return ::FindCachedDefaultFormat(aDefaultFormatKeys, nSearch);
+}
+
+// static
+sal_uInt32 SvNFEngine::ImpGetDefaultFormat(const SvNFFormatData& rFormatData, SvNumFormatType nType, sal_uInt32 CLOffset)
+{
+ sal_uInt32 nDefaultFormat = NUMBERFORMAT_ENTRY_NOT_FOUND;
+
+ // look for a defined standard
+ sal_uInt32 nStopKey = CLOffset + SV_COUNTRY_LANGUAGE_OFFSET;
+ sal_uInt32 nKey(0);
+ auto it2 = rFormatData.aFTable.find( CLOffset );
+ while ( it2 != rFormatData.aFTable.end() && (nKey = it2->first ) >= CLOffset && nKey < nStopKey )
+ {
+ const SvNumberformat* pEntry = it2->second.get();
+ if ( pEntry->IsStandard() && (pEntry->GetMaskedType() == nType) )
{
- const SvNumberformat* pEntry = it2->second.get();
- if ( pEntry->IsStandard() && (pEntry->GetMaskedType() == nType) )
- {
- nDefaultFormat = nKey;
- break; // while
- }
- ++it2;
+ nDefaultFormat = nKey;
+ break; // while
}
+ ++it2;
+ }
- if ( nDefaultFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
- { // none found, use old fixed standards
- switch( nType )
- {
- case SvNumFormatType::DATE:
- nDefaultFormat = CLOffset + ZF_STANDARD_DATE;
- break;
- case SvNumFormatType::TIME:
- nDefaultFormat = CLOffset + ZF_STANDARD_TIME+1;
- break;
- case SvNumFormatType::DATETIME:
- nDefaultFormat = CLOffset + ZF_STANDARD_DATETIME;
- break;
- case SvNumFormatType::DURATION:
- nDefaultFormat = CLOffset + ZF_STANDARD_DURATION;
- break;
- case SvNumFormatType::PERCENT:
- nDefaultFormat = CLOffset + ZF_STANDARD_PERCENT+1;
- break;
- case SvNumFormatType::SCIENTIFIC:
- nDefaultFormat = CLOffset + ZF_STANDARD_SCIENTIFIC;
- break;
- default:
- nDefaultFormat = CLOffset + ZF_STANDARD;
- }
+ if ( nDefaultFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
+ { // none found, use old fixed standards
+ switch( nType )
+ {
+ case SvNumFormatType::DATE:
+ nDefaultFormat = CLOffset + ZF_STANDARD_DATE;
+ break;
+ case SvNumFormatType::TIME:
+ nDefaultFormat = CLOffset + ZF_STANDARD_TIME+1;
+ break;
+ case SvNumFormatType::DATETIME:
+ nDefaultFormat = CLOffset + ZF_STANDARD_DATETIME;
+ break;
+ case SvNumFormatType::DURATION:
+ nDefaultFormat = CLOffset + ZF_STANDARD_DURATION;
+ break;
+ case SvNumFormatType::PERCENT:
+ nDefaultFormat = CLOffset + ZF_STANDARD_PERCENT+1;
+ break;
+ case SvNumFormatType::SCIENTIFIC:
+ nDefaultFormat = CLOffset + ZF_STANDARD_SCIENTIFIC;
+ break;
+ default:
+ nDefaultFormat = CLOffset + ZF_STANDARD;
}
- bShouldCache = true;
}
- return std::make_pair(nDefaultFormat, bShouldCache);
+
+ return nDefaultFormat;
}
sal_uInt32 SvNumberFormatter::GetStandardFormat( sal_uInt32 nFIndex, SvNumFormatType eType,
@@ -3912,9 +3925,19 @@ sal_uInt32 SvNFEngine::GetCLOffsetRO(const SvNFFormatData& rFormatData, SvNFLang
return nCLOffset;
}
-void SvNFEngine::CacheFormatRO(const SvNFFormatData&, sal_uInt32, sal_uInt32)
+// we can't cache to SvNFFormatData in RO mode, so cache to a temp map which we can consult pre-thread in FindFormatRO
+// caches can be merged with SvNumberFormatter::MergeDefaultFormatKeys
+void SvNFEngine::CacheFormatRO(SvNFFormatData::DefaultFormatKeysMap& rFormatCache, sal_uInt32 nSearch, sal_uInt32 nFormat)
{
- assert(false && "not really fatal, just not cached");
+ rFormatCache[nSearch] = nFormat;
+}
+
+sal_uInt32 SvNFEngine::FindFormatRO(const SvNFFormatData& rFormatData, const SvNFFormatData::DefaultFormatKeysMap& rFormatCache, sal_uInt32 nSearch)
+{
+ sal_uInt32 nFormat = rFormatData.FindCachedDefaultFormat(nSearch);
+ if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
+ return nFormat;
+ return ::FindCachedDefaultFormat(rFormatCache, nSearch);
}
sal_uInt32 SvNFEngine::GetCLOffsetRW(SvNFFormatData& rFormatData, SvNFLanguageData& rCurrentLanguage, const NativeNumberWrapper* pNatNum, LanguageType eLnge)
@@ -3927,6 +3950,11 @@ void SvNFEngine::CacheFormatRW(SvNFFormatData& rFormatData, sal_uInt32 nSearch,
rFormatData.aDefaultFormatKeys[nSearch] = nFormat;
}
+sal_uInt32 SvNFEngine::FindFormatRW(const SvNFFormatData& rFormatData, sal_uInt32 nSearch)
+{
+ return rFormatData.FindCachedDefaultFormat(nSearch);
+}
+
sal_uInt32 SvNFEngine::DefaultCurrencyRW(SvNFFormatData& rFormatData, SvNFLanguageData& rCurrentLanguage, const NativeNumberWrapper* pNatNum, sal_uInt32 CLOffset, LanguageType eLnge)
{
if (eLnge == LANGUAGE_SYSTEM)
@@ -3953,16 +3981,18 @@ SvNFEngine::Accessor SvNFEngine::GetRWPolicy(SvNFFormatData& rFormatData)
{
std::bind(SvNFEngine::GetCLOffsetRW, std::ref(rFormatData), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3),
std::bind(SvNFEngine::CacheFormatRW, std::ref(rFormatData), std::placeholders::_1, std::placeholders::_2),
+ std::bind(SvNFEngine::FindFormatRW, std::ref(rFormatData), std::placeholders::_1),
std::bind(SvNFEngine::DefaultCurrencyRW, std::ref(rFormatData), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)
};
}
-SvNFEngine::Accessor SvNFEngine::GetROPolicy(const SvNFFormatData& rFormatData)
+SvNFEngine::Accessor SvNFEngine::GetROPolicy(const SvNFFormatData& rFormatData, SvNFFormatData::DefaultFormatKeysMap& rFormatCache)
{
return
{
std::bind(SvNFEngine::GetCLOffsetRO, std::ref(rFormatData), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3),
- std::bind(SvNFEngine::CacheFormatRO, std::ref(rFormatData), std::placeholders::_1, std::placeholders::_2),
+ std::bind(SvNFEngine::CacheFormatRO, std::ref(rFormatCache), std::placeholders::_1, std::placeholders::_2),
+ std::bind(SvNFEngine::FindFormatRO, std::ref(rFormatData), std::ref(rFormatCache), std::placeholders::_1),
std::bind(SvNFEngine::DefaultCurrencyRO, std::ref(rFormatData), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)
};
}
@@ -4355,6 +4385,24 @@ bool SvNumberFormatter::ImpLookupCurrencyEntryLoopBody(
return true;
}
+void SvNFFormatData::MergeDefaultFormatKeys(const DefaultFormatKeysMap& rDefaultFormatKeys)
+{
+ for (const auto& r : rDefaultFormatKeys)
+ {
+#ifndef NDEBUG
+ auto iter = aDefaultFormatKeys.find(r.first);
+ assert(iter == aDefaultFormatKeys.end() || iter->second == r.second);
+#endif
+ aDefaultFormatKeys[r.first] = r.second;
+ }
+}
+
+void SvNumberFormatter::MergeDefaultFormatKeys(const SvNFFormatData::DefaultFormatKeysMap& rDefaultFormatKeys)
+{
+ ::osl::MutexGuard aGuard( GetInstanceMutex() );
+ m_aFormatData.MergeDefaultFormatKeys(rDefaultFormatKeys);
+}
+
bool SvNFFormatData::GetNewCurrencySymbolString(sal_uInt32 nFormat, OUString& rStr,
const NfCurrencyEntry** ppEntry /* = NULL */,
bool* pBank /* = NULL */) const