Kaydet (Commit) 0b80ff00 authored tarafından Eike Rathke's avatar Eike Rathke

handle canonicalization better and share impl

Change-Id: I82c1b899f88e348cfa798558b63b2264d997c33b
üst d5295408
...@@ -610,27 +610,25 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly() ...@@ -610,27 +610,25 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly()
return pImpl; return pImpl;
} }
LanguageType nLang = getNextOnTheFlyLanguage();
if (!nLang)
{
// out of IDs, nothing to register
return pImpl;
}
mnLangID = nLang;
mbInitializedLangID = true;
osl::MutexGuard aGuard( theMutex::get()); osl::MutexGuard aGuard( theMutex::get());
MapBcp47& rMap = theMapBcp47::get(); MapBcp47& rMap = theMapBcp47::get();
MapBcp47::const_iterator it( rMap.find( maBcp47)); MapBcp47::const_iterator it( rMap.find( maBcp47));
bool bOtherImpl = false;
if (it != rMap.end()) if (it != rMap.end())
{ {
SAL_INFO( "i18nlangtag", "LanguageTag::registerOnTheFly: found impl for '" << maBcp47 << "'"); SAL_INFO( "i18nlangtag", "LanguageTag::registerOnTheFly: found impl for '" << maBcp47 << "'");
pImpl = (*it).second; pImpl = (*it).second;
if (pImpl.get() != this) if (pImpl.get() != this)
{ {
SAL_WARN( "i18nlangtag", "LanguageTag::registerOnTheFly: impl should be this for '" << maBcp47 << "'"); // Could happen for example if during registerImpl() the tag was
*pImpl = *this; // ensure consistency // changed via canonicalize() and the result was already present in
// the map before, for example 'bn-Beng' => 'bn'. This specific
// case is now taken care of in registerImpl() and doesn't reach
// here. However, use the already existing impl if it matches.
SAL_WARN( "i18nlangtag", "LanguageTag::registerOnTheFly: using other impl for this '" << maBcp47 << "'");
*this = *pImpl; // ensure consistency
bOtherImpl = true;
} }
} }
else else
...@@ -640,6 +638,23 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly() ...@@ -640,6 +638,23 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly()
rMap.insert( ::std::make_pair( maBcp47, pImpl)); rMap.insert( ::std::make_pair( maBcp47, pImpl));
} }
if (!bOtherImpl || !pImpl->mbInitializedLangID)
{
LanguageType nLang = getNextOnTheFlyLanguage();
if (!nLang)
{
// out of IDs, nothing to register
return pImpl;
}
pImpl->mnLangID = nLang;
pImpl->mbInitializedLangID = true;
if (pImpl.get() != this)
{
mnLangID = nLang;
mbInitializedLangID = true;
}
}
::std::pair< MapLangID::const_iterator, bool > res( ::std::pair< MapLangID::const_iterator, bool > res(
theMapLangID::get().insert( ::std::make_pair( pImpl->mnLangID, pImpl))); theMapLangID::get().insert( ::std::make_pair( pImpl->mnLangID, pImpl)));
if (res.second) if (res.second)
...@@ -831,15 +846,33 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const ...@@ -831,15 +846,33 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const
{ {
SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: new impl for '" << maBcp47 << "'"); SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: new impl for '" << maBcp47 << "'");
pImpl.reset( new LanguageTagImpl( *this)); pImpl.reset( new LanguageTagImpl( *this));
rMap.insert( ::std::make_pair( maBcp47, pImpl)); ::std::pair< MapBcp47::iterator, bool > insOrig( rMap.insert( ::std::make_pair( maBcp47, pImpl)));
// If changed after canonicalize() also add the resulting tag to map. // If changed after canonicalize() also add the resulting tag to
// the map.
if (pImpl->synCanonicalize()) if (pImpl->synCanonicalize())
{ {
SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: canonicalized to '" << pImpl->maBcp47 << "'"); SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: canonicalized to '" << pImpl->maBcp47 << "'");
bool bInserted = rMap.insert( ::std::make_pair( pImpl->maBcp47, pImpl)).second; ::std::pair< MapBcp47::const_iterator, bool > insCanon(
SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: " << (bInserted ? "" : "not ") << "inserted '" rMap.insert( ::std::make_pair( pImpl->maBcp47, pImpl)));
<< pImpl->maBcp47 << "'"); SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: " << (insCanon.second ? "" : "not ")
<< "inserted '" << pImpl->maBcp47 << "'");
// If the canonicalized tag already existed (was not inserted)
// and impls are different, make this impl that impl and skip
// the rest if that LangID is present as well. The existing
// entry may or may not be different, it may even be strictly
// identical to this if it differs only in case (e.g. ko-kr =>
// ko-KR) which was corrected in canonicalize() hence also in
// the map entry but comparison is case insensitive and found
// it again.
if (!insCanon.second && (*insCanon.first).second != pImpl)
{
(*insOrig.first).second = pImpl = (*insCanon.first).second;
SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: share impl with 0x"
<< ::std::hex << pImpl->mnLangID);
}
} }
if (!pImpl->mbInitializedLangID)
{
// Try round-trip Bcp47->Locale->LangID->Locale->Bcp47. // Try round-trip Bcp47->Locale->LangID->Locale->Bcp47.
if (!pImpl->mbInitializedLocale) if (!pImpl->mbInitializedLocale)
pImpl->convertBcp47ToLocale(); pImpl->convertBcp47ToLocale();
...@@ -882,6 +915,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const ...@@ -882,6 +915,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const
} }
} }
} }
}
else else
{ {
SAL_WARN( "i18nlangtag", "LanguageTag::registerImpl: can't register for 0x" << ::std::hex << mnLangID ); SAL_WARN( "i18nlangtag", "LanguageTag::registerImpl: can't register for 0x" << ::std::hex << mnLangID );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment