sw/source/filter/inc/msfilter.hxx       |   14 ++++++++++--
 sw/source/filter/ww8/writerwordglue.cxx |   35 ++++++++++++++++++++++----------
 sw/source/filter/ww8/ww8par2.cxx        |   33 +++++++++++++++++++++---------
 sw/source/filter/ww8/ww8par2.hxx        |    8 +++++--
 4 files changed, 67 insertions(+), 23 deletions(-)

New commits:
commit f5f946e707cb8beda0e4ae790aa65abbf61b3083
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Sun Jun 19 20:46:06 2022 +0100
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Sun Jun 19 22:56:19 2022 +0200

    ofz#47706 Timeout
    
    2m34s->1.6s
    
    Change-Id: I2370237e07d6e2a45c831c70ac1c1158efef7816
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136107
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/sw/source/filter/inc/msfilter.hxx 
b/sw/source/filter/inc/msfilter.hxx
index b2696c2d7ddc..1a3626bdd521 100644
--- a/sw/source/filter/inc/msfilter.hxx
+++ b/sw/source/filter/inc/msfilter.hxx
@@ -162,6 +162,10 @@ namespace sw
                 in knowing if the style has either a builtin standard id, or is
                 a user defined style.
 
+                @param rCollisions
+                Cache of previous name collisions to speed up resolution
+                of later duplicates.
+
                 @return
                 The equivalent writer style packaged as a StyleResult to use
                 for this word style.
@@ -171,7 +175,8 @@ namespace sw
                 rName and WW-rName[0..SAL_MAX_INT32], which is both unlikely
                 and impossible.
             */
-            StyleResult GetStyle(const OUString& rName, ww::sti eSti);
+            StyleResult GetStyle(const OUString& rName, ww::sti eSti,
+                                 std::map<OUString, sal_Int32>& rCollisions);
         };
 
         /** Knows which writer style a given word style should be imported as
@@ -219,6 +224,10 @@ namespace sw
                 in knowing if the style has either a builtin standard id, or is
                 a user defined style.
 
+                @param rCollisions
+                Cache of previous name collisions to speed up resolution
+                of later duplicates.
+
                 @return
                 The equivalent writer style packaged as a StyleResult to use
                 for this word style.
@@ -228,7 +237,8 @@ namespace sw
                 rName and WW-rName[0..SAL_MAX_INT32], which is both unlikely
                 and impossible.
             */
-            StyleResult GetStyle(const OUString& rName, ww::sti eSti);
+            StyleResult GetStyle(const OUString& rName, ww::sti eSti,
+                                 std::map<OUString, sal_Int32>& rCollisions);
         };
 
         /** Find suitable names for exporting this font
diff --git a/sw/source/filter/ww8/writerwordglue.cxx 
b/sw/source/filter/ww8/writerwordglue.cxx
index ec46c3e35742..6d1f40c556b2 100644
--- a/sw/source/filter/ww8/writerwordglue.cxx
+++ b/sw/source/filter/ww8/writerwordglue.cxx
@@ -242,16 +242,19 @@ namespace myImplHelpers
     private:
         MapperImpl<C> maHelper;
         o3tl::sorted_vector<const C*> maUsedStyles;
-        C* MakeNonCollidingStyle(const OUString& rName);
+        C* MakeNonCollidingStyle(const OUString& rName,
+                                 std::map<OUString, sal_Int32>& rCollisions);
     public:
         typedef std::pair<C*, bool> StyleResult;
         explicit StyleMapperImpl(SwDoc &rDoc) : maHelper(rDoc) {}
-        StyleResult GetStyle(const OUString& rName, ww::sti eSti);
+        StyleResult GetStyle(const OUString& rName, ww::sti eSti,
+                             std::map<OUString, sal_Int32>& rCollisions);
     };
 
     template<class C>
     typename StyleMapperImpl<C>::StyleResult
-    StyleMapperImpl<C>::GetStyle(const OUString& rName, ww::sti eSti)
+    StyleMapperImpl<C>::GetStyle(const OUString& rName, ww::sti eSti,
+                                 std::map<OUString, sal_Int32>& rCollisions)
     {
         C *pRet = maHelper.GetBuiltInStyle(eSti);
 
@@ -276,7 +279,7 @@ namespace myImplHelpers
             // No commas allow in SW style names
             if (-1 != nIdx)
                 aName = rName.copy( 0, nIdx );
-            pRet = MakeNonCollidingStyle( aName );
+            pRet = MakeNonCollidingStyle(aName, rCollisions);
         }
 
         if (pRet)
@@ -286,7 +289,8 @@ namespace myImplHelpers
     }
 
     template<class C>
-    C* StyleMapperImpl<C>::MakeNonCollidingStyle(const OUString& rName)
+    C* StyleMapperImpl<C>::MakeNonCollidingStyle(const OUString& rName,
+                                                 std::map<OUString, 
sal_Int32>& rCollisions)
     {
         OUString aName(rName);
         C* pColl = nullptr;
@@ -299,8 +303,15 @@ namespace myImplHelpers
             if (!aName.startsWith("WW-"))
                 aName = "WW-" + aName;
 
-            sal_Int32 nI = 1;
             OUString aBaseName = aName;
+            sal_Int32 nI = 1;
+
+            // if we've seen this basename before then start at
+            // where we finished the last time
+            auto aFind = rCollisions.find(aBaseName);
+            if (aFind != rCollisions.end())
+                nI = aFind->second;
+
             while (
                     nullptr != (pColl = maHelper.GetStyle(aName)) &&
                     (nI < SAL_MAX_INT32)
@@ -308,6 +319,8 @@ namespace myImplHelpers
             {
                 aName = aBaseName + OUString::number(nI++);
             }
+
+            rCollisions.insert_or_assign(aBaseName, nI);
         }
 
         return pColl ? nullptr : maHelper.MakeStyle(aName);
@@ -462,9 +475,10 @@ namespace sw
         }
 
         ParaStyleMapper::StyleResult ParaStyleMapper::GetStyle(
-            const OUString& rName, ww::sti eSti)
+            const OUString& rName, ww::sti eSti,
+            std::map<OUString, sal_Int32>& rCollisions)
         {
-            return mpImpl->GetStyle(rName, eSti);
+            return mpImpl->GetStyle(rName, eSti, rCollisions);
         }
 
         CharStyleMapper::CharStyleMapper(SwDoc &rDoc)
@@ -477,9 +491,10 @@ namespace sw
         }
 
         CharStyleMapper::StyleResult CharStyleMapper::GetStyle(
-            const OUString& rName, ww::sti eSti)
+            const OUString& rName, ww::sti eSti,
+            std::map<OUString, sal_Int32>& rCollisions)
         {
-            return mpImpl->GetStyle(rName, eSti);
+            return mpImpl->GetStyle(rName, eSti, rCollisions);
         }
 
         FontMapExport::FontMapExport(std::u16string_view rFamilyName)
diff --git a/sw/source/filter/ww8/ww8par2.cxx b/sw/source/filter/ww8/ww8par2.cxx
index ec90df03c8d9..f38bde4ac35a 100644
--- a/sw/source/filter/ww8/ww8par2.cxx
+++ b/sw/source/filter/ww8/ww8par2.cxx
@@ -3799,7 +3799,10 @@ void WW8RStyle::Set1StyleDefaults()
     }
 }
 
-bool WW8RStyle::PrepareStyle(SwWW8StyInf &rSI, ww::sti eSti, sal_uInt16 
nThisStyle, sal_uInt16 nNextStyle)
+bool WW8RStyle::PrepareStyle(SwWW8StyInf &rSI, ww::sti eSti, sal_uInt16 
nThisStyle,
+                             sal_uInt16 nNextStyle,
+                             std::map<OUString, sal_Int32>& rParaCollisions,
+                             std::map<OUString, sal_Int32>& rCharCollisions)
 {
     SwFormat* pColl;
     bool bStyExist;
@@ -3808,7 +3811,7 @@ bool WW8RStyle::PrepareStyle(SwWW8StyInf &rSI, ww::sti 
eSti, sal_uInt16 nThisSty
     {
         // Para-Style
         sw::util::ParaStyleMapper::StyleResult aResult =
-            mpIo->m_aParaStyleMapper.GetStyle(rSI.GetOrgWWName(), eSti);
+            mpIo->m_aParaStyleMapper.GetStyle(rSI.GetOrgWWName(), eSti, 
rParaCollisions);
         pColl = aResult.first;
         bStyExist = aResult.second;
     }
@@ -3816,7 +3819,7 @@ bool WW8RStyle::PrepareStyle(SwWW8StyInf &rSI, ww::sti 
eSti, sal_uInt16 nThisSty
     {
         // Char-Style
         sw::util::CharStyleMapper::StyleResult aResult =
-            mpIo->m_aCharStyleMapper.GetStyle(rSI.GetOrgWWName(), eSti);
+            mpIo->m_aCharStyleMapper.GetStyle(rSI.GetOrgWWName(), eSti, 
rCharCollisions);
         pColl = aResult.first;
         bStyExist = aResult.second;
     }
@@ -3905,7 +3908,9 @@ void WW8RStyle::PostStyle(SwWW8StyInf const &rSI, bool 
bOldNoImp)
     mpIo->m_nListLevel = MAXLEVEL;
 }
 
-void WW8RStyle::Import1Style( sal_uInt16 nNr )
+void WW8RStyle::Import1Style(sal_uInt16 nNr,
+                             std::map<OUString, sal_Int32>& rParaCollisions,
+                             std::map<OUString, sal_Int32>& rCharCollisions)
 {
     if (nNr >= mpIo->m_vColl.size())
         return;
@@ -3920,14 +3925,14 @@ void WW8RStyle::Import1Style( sal_uInt16 nNr )
     // valid and not NUL and not yet imported
 
     if( rSI.m_nBase < m_cstd && !mpIo->m_vColl[rSI.m_nBase].m_bImported )
-        Import1Style( rSI.m_nBase );
+        Import1Style(rSI.m_nBase, rParaCollisions, rCharCollisions);
 
     mpStStrm->Seek( rSI.m_nFilePos );
 
     sal_uInt16 nSkip;
     OUString sName;
 
-    std::unique_ptr<WW8_STD> xStd(Read1Style(nSkip, &sName));// read Style
+    std::unique_ptr<WW8_STD> xStd(Read1Style(nSkip, &sName)); // read Style
 
     if (xStd)
         rSI.SetOrgWWIdent( sName, xStd->sti );
@@ -3941,7 +3946,9 @@ void WW8RStyle::Import1Style( sal_uInt16 nNr )
         return;
     }
 
-    bool bOldNoImp = PrepareStyle(rSI, static_cast<ww::sti>(xStd->sti), nNr, 
xStd->istdNext);
+    bool bOldNoImp = PrepareStyle(rSI, static_cast<ww::sti>(xStd->sti),
+                                  nNr, xStd->istdNext,
+                                  rParaCollisions, rCharCollisions);
 
     // if something is interpreted wrong, this should make it work again
     sal_uInt64 nPos = mpStStrm->Tell();
@@ -4461,6 +4468,9 @@ void WW8RStyle::ImportOldFormatStyles()
 
     if (iMac > nStyles) iMac = nStyles;
 
+    std::map<OUString, sal_Int32> aParaCollisions;
+    std::map<OUString, sal_Int32> aCharCollisions;
+
     for (stcp = 0; stcp < iMac; ++stcp)
     {
         sal_uInt8 stcNext(0), stcBase(0);
@@ -4492,7 +4502,9 @@ void WW8RStyle::ImportOldFormatStyles()
         if (ww::StandardStiIsCharStyle(eSti) && !aPAPXOffsets[stcp].mnSize)
             mpIo->m_vColl[stc].m_bColl = false;
 
-        bool bOldNoImp = PrepareStyle(rSI, eSti, stc, stcNext);
+        bool bOldNoImp = PrepareStyle(rSI, eSti, stc, stcNext,
+                                      aParaCollisions,
+                                      aCharCollisions);
 
         ImportSprms(aPAPXOffsets[stcp].mnOffset, aPAPXOffsets[stcp].mnSize,
             true);
@@ -4510,9 +4522,12 @@ void WW8RStyle::ImportNewFormatStyles()
 {
     ScanStyles();                       // Scan Based On
 
+    std::map<OUString, sal_Int32> aParaCollisions;
+    std::map<OUString, sal_Int32> aCharCollisions;
+
     for (sal_uInt16 i = 0; i < m_cstd; ++i) // import Styles
         if (mpIo->m_vColl[i].m_bValid)
-            Import1Style( i );
+            Import1Style(i, aParaCollisions, aCharCollisions);
 }
 
 void WW8RStyle::Import()
diff --git a/sw/source/filter/ww8/ww8par2.hxx b/sw/source/filter/ww8/ww8par2.hxx
index c43ff044598c..c486d1b93864 100644
--- a/sw/source/filter/ww8/ww8par2.hxx
+++ b/sw/source/filter/ww8/ww8par2.hxx
@@ -117,14 +117,18 @@ friend class SwWW8ImplReader;
     short ImportUPX(short nLen, bool bPAP, bool bOdd);
 
     void Set1StyleDefaults();
-    void Import1Style(sal_uInt16 nNr);
+    void Import1Style(sal_uInt16 nNr,
+                      std::map<OUString, sal_Int32>& rParaCollisions,
+                      std::map<OUString, sal_Int32>& rCharCollisions);
     void RecursiveReg(sal_uInt16 nNr);
 
     void ImportNewFormatStyles();
     void ScanStyles();
     void ImportOldFormatStyles();
 
-    bool PrepareStyle(SwWW8StyInf &rSI, ww::sti eSti, sal_uInt16 nThisStyle, 
sal_uInt16 nNextStyle);
+    bool PrepareStyle(SwWW8StyInf &rSI, ww::sti eSti, sal_uInt16 nThisStyle, 
sal_uInt16 nNextStyle,
+                      std::map<OUString, sal_Int32>& rParaCollisions,
+                      std::map<OUString, sal_Int32>& rCharCollisions);
     void PostStyle(SwWW8StyInf const &rSI, bool bOldNoImp);
 
     WW8RStyle(const WW8RStyle&) = delete;

Reply via email to