diff options
author | Eike Rathke <erack@redhat.com> | 2013-10-17 18:33:47 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2013-10-17 18:36:05 +0200 |
commit | c450aafad00da4553fc6f7abadb19b4b16df6b88 (patch) | |
tree | 1521226863a3fba436f010f68b307f96c0d45dfb /i18nlangtag/source/languagetag/languagetag.cxx | |
parent | 7bbd58eafc3146abcefc73d2d1ca6869bb47ef5a (diff) |
solve the 'dz' vs 'bo' and 'nn', 'nb' and 'nn' share primary ID cases
Change-Id: I7ccead4493c9848b55f642c2636daa3c60aeb7a6
Diffstat (limited to 'i18nlangtag/source/languagetag/languagetag.cxx')
-rw-r--r-- | i18nlangtag/source/languagetag/languagetag.cxx | 71 |
1 files changed, 50 insertions, 21 deletions
diff --git a/i18nlangtag/source/languagetag/languagetag.cxx b/i18nlangtag/source/languagetag/languagetag.cxx index fc1f5b53eb09..4f8af9ade4bb 100644 --- a/i18nlangtag/source/languagetag/languagetag.cxx +++ b/i18nlangtag/source/languagetag/languagetag.cxx @@ -309,8 +309,10 @@ private: /** Generates on-the-fly LangID and registers the maBcp47,mnLangID pair. @param nRegisterID - If not 0 and not LANGUAGE_DONTKNOW, use that ID instead of - generating an on-the-fly ID. + If not 0 and not LANGUAGE_DONTKNOW, suggest (!) to use that ID + instead of generating an on-the-fly ID. Implementation may + still generate an ID if the suggested ID is already used for + another language tag. @return NULL if no ID could be obtained or registration failed. */ @@ -616,10 +618,10 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly( LanguageType nRegisterID osl::MutexGuard aGuard( theMutex::get()); - MapBcp47& rMap = theMapBcp47::get(); - MapBcp47::const_iterator it( rMap.find( maBcp47)); + MapBcp47& rMapBcp47 = theMapBcp47::get(); + MapBcp47::const_iterator it( rMapBcp47.find( maBcp47)); bool bOtherImpl = false; - if (it != rMap.end()) + if (it != rMapBcp47.end()) { SAL_INFO( "i18nlangtag", "LanguageTag::registerOnTheFly: found impl for '" << maBcp47 << "'"); pImpl = (*it).second; @@ -639,23 +641,47 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly( LanguageType nRegisterID { SAL_INFO( "i18nlangtag", "LanguageTag::registerOnTheFly: new impl for '" << maBcp47 << "'"); pImpl.reset( new LanguageTagImpl( *this)); - rMap.insert( ::std::make_pair( maBcp47, pImpl)); + rMapBcp47.insert( ::std::make_pair( maBcp47, pImpl)); } if (!bOtherImpl || !pImpl->mbInitializedLangID) { - LanguageType nLang = ((nRegisterID == 0 || nRegisterID == LANGUAGE_DONTKNOW) ? - getNextOnTheFlyLanguage() : nRegisterID); - if (!nLang) + if (nRegisterID == 0 || nRegisterID == LANGUAGE_DONTKNOW) + nRegisterID = getNextOnTheFlyLanguage(); + else + { + // Accept a suggested ID only if it is not mapped yet to something + // different, otherwise we would end up with ambiguous assignments + // of different language tags, for example for the same primary + // LangID with "no", "nb" and "nn". + const MapLangID& rMapLangID = theMapLangID::get(); + MapLangID::const_iterator itID( rMapLangID.find( nRegisterID)); + if (itID != rMapLangID.end()) + { + if ((*itID).second->maBcp47 != maBcp47) + { + SAL_INFO( "i18nlangtag", "LanguageTag::registerOnTheFly: not using suggested 0x" + << ::std::hex << nRegisterID << " for '" << maBcp47 << "' have '" + << (*itID).second->maBcp47 << "'"); + nRegisterID = getNextOnTheFlyLanguage(); + } + else + { + SAL_WARN( "i18nlangtag", "LanguageTag::registerOnTheFly: suggested 0x" + << ::std::hex << nRegisterID << " for '" << maBcp47 << "' already registered"); + } + } + } + if (!nRegisterID) { // out of IDs, nothing to register return pImpl; } - pImpl->mnLangID = nLang; + pImpl->mnLangID = nRegisterID; pImpl->mbInitializedLangID = true; if (pImpl.get() != this) { - mnLangID = nLang; + mnLangID = nRegisterID; mbInitializedLangID = true; } } @@ -678,6 +704,13 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly( LanguageType nRegisterID } +static bool lcl_isKnownOnTheFlyID( LanguageType nLang ) +{ + return nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM && + (LanguageTag::isOnTheFlyID( nLang) || (nLang == MsLangId::getPrimaryLanguage( nLang))); +} + + LanguageTag::ImplPtr LanguageTag::registerImpl() const { // XXX NOTE: Do not use non-static LanguageTag::convert...() member methods @@ -884,10 +917,8 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const if (!pImpl->mbInitializedLangID) pImpl->convertLocaleToLang( true); // Unconditionally insert (round-trip is possible) for - // on-the-fly IDs and (generated or not) primary language IDs. - bool bInsert = (pImpl->mnLangID != LANGUAGE_DONTKNOW && - (LanguageTag::isOnTheFlyID( pImpl->mnLangID) || - (pImpl->mnLangID == MsLangId::getPrimaryLanguage( pImpl->mnLangID)))); + // on-the-fly IDs and (generated or not) suggested IDs. + bool bInsert = lcl_isKnownOnTheFlyID( pImpl->mnLangID); OUString aBcp47; if (!bInsert) { @@ -1309,8 +1340,8 @@ void LanguageTagImpl::convertLocaleToLang( bool bAllowOnTheFlyID ) if (isValidBcp47()) { // For language-only (including script) look if we know some - // locale of that language and if so use the primary language - // ID of that instead of generating an on-the-fly-ID. + // locale of that language and if so try to use the primary + // language ID of that instead of generating an on-the-fly ID. if (getCountry().isEmpty() && isIsoODF()) { lang::Locale aLoc( MsLangId::Conversion::lookupFallbackLocale( maLocale)); @@ -1319,10 +1350,8 @@ void LanguageTagImpl::convertLocaleToLang( bool bAllowOnTheFlyID ) if (aLoc.Language != "en" || getLanguage() == "en") { mnLangID = MsLangId::Conversion::convertLocaleToLanguage( aLoc); - // LANGUAGE_DONTKNOW is all bits of primary language, - // so this is ok even if the conversion failed, which - // it should not anyway.. - mnLangID = MsLangId::getPrimaryLanguage( mnLangID); + if (mnLangID != LANGUAGE_DONTKNOW) + mnLangID = MsLangId::getPrimaryLanguage( mnLangID); } } registerOnTheFly( mnLangID); |